Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve cloud capacity (CU / SU) calculation #966

Open
renauter opened this issue Apr 11, 2024 · 0 comments
Open

Improve cloud capacity (CU / SU) calculation #966

renauter opened this issue Apr 11, 2024 · 0 comments

Comments

@renauter
Copy link
Collaborator

Is your feature request related to a problem? Please describe

When we calculate SU and CU (integer values) we do some integer divisions which leads to some precision error.

Describe the solution you'd like

A better approach would be to deal with float divisions and round result to closest integer before converting back to integer.
With this we would get more accurate values.

Additional context

Example of precision error while calculating SU / CU for node 6705

image

Simulated calculation from rust tfchain code:

const GIGABYTE: u128 = 1024 * 1024 * 1024;
const ONE_THOUSAND: u128 = 1000;
const CRU: u64 = 12;
const MRU: u64 = 67036315648;
const SRU: u64 = 1000204886016;
const HRU: u64 = 0;

fn calc_cu() -> u64 {
    let cru_min = CRU as u128 * 2 * GIGABYTE * ONE_THOUSAND;
    let mru_min =
        ((MRU as u128).checked_sub(1).unwrap_or(0) * GIGABYTE) * ONE_THOUSAND / 4;
    let sru_min = SRU as u128 * ONE_THOUSAND / 50;

    if cru_min < mru_min && cru_min < sru_min {
        cru_min as u64
    } else if mru_min < cru_min && mru_min < sru_min {
        mru_min as u64
    } else if sru_min < cru_min && sru_min < mru_min {
        sru_min as u64
    } else {
        0
    }
}
    
fn get_cu() -> u64 {
    let cu = calc_cu();
    let calculated_cu = 2 * (cu as u128 / GIGABYTE / ONE_THOUSAND);
    calculated_cu as u64
}
    
fn get_su() -> u64 {
    let su = HRU as u128 * ONE_THOUSAND / 1200 + SRU as u128 * ONE_THOUSAND / 250;
    let calculated_su = su / GIGABYTE;
    let result = calculated_su as u128 / ONE_THOUSAND;
    result as u64
}

fn main() {
    println!("CU: {}", get_cu());
    println!("SU: {}", get_su());
}

Copy past previous code in rust playground https://play.rust-lang.org/ and run gives:

CU: 36
SU: 3

While calculating using float would give:

>>> GIGABYTE = 1024 * 1024 * 1024
>>> cru = 12
>>> mru = 67036315648
>>> sru = 1000204886016
>>> hru = 0
>>> cru_min = cru * 2 * GIGABYTE * 1000
>>> cru_min
25769803776000
>>> mru_min = ((mru - 1) * GIGABYTE) * 1000 / 4
>>> mru_min
1.799492395926238e+22
>>> sru_min = sru * 1000 / 50
>>> sru_min
20004097720320.0
>>> sru_min < cru_min and sru_min < mru_min
True
>>> cu = sru_min
>>> 2 * (cu / GIGABYTE / 1000)
37.26053558349609
>>> su = hru * 1000 / 1200 + sru * 1000 / 250
>>> su / GIGABYTE / 1000
3.7260535583496095
CU: 37
SU: 4
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant