sipp icon indicating copy to clipboard operation
sipp copied to clipboard

Initialize srand with hostname and PID

Open FalacerSelene opened this issue 1 year ago • 5 comments

We're running SIPp in a container scaleset, and ran into an issue where two instances started in the same second and continually picked the same random numbers as each other, which meant that InputFileRandomOrder actually had the instances continually 'randomly' picking the same entries.

To avoid this, this change adds a bit more noise to the start-of-day call to srand(), mixing in the PID and the hostname, which would avoid two instances using the same seed.

I'd welcome an alternative and better way to do this!

FalacerSelene avatar Aug 01 '24 10:08 FalacerSelene

Claude suggested this:

unsigned int generate_seed() {
    unsigned int seed = (unsigned int)time(NULL);
    seed ^= (unsigned int)clock();
    seed ^= (unsigned int)getpid();
    
    struct timespec ts;
    if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) {
        seed ^= (unsigned int)ts.tv_nsec;
    }
    
    return seed;
}

WDYS?

orgads avatar Aug 01 '24 11:08 orgads

Claude suggested this:

unsigned int generate_seed() {
    unsigned int seed = (unsigned int)time(NULL);
    seed ^= (unsigned int)clock();
    seed ^= (unsigned int)getpid();
    
    struct timespec ts;
    if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) {
        seed ^= (unsigned int)ts.tv_nsec;
    }
    
    return seed;
}

WDYS?

I don't think we gain from mixing 3 different time-based values (time(), clock() and clock_gettime()) - that still gives only time-based uniqueness. So I'd probably just take clock_gettime()'s nanoseconds and forget about time() and clock() in that case, because it's incredibly unlikely that two processes call that in the same ns.

However, clock_getres() might indicate the resolution isn't really to the nanosecond. Since we don't know the resolution of the clock across systems that sipp might run on, I thought it was better to grab other sources of uniqueness (PID and hostname).

But a suggestion like this would almost definitely solve my problem too :)

FalacerSelene avatar Aug 01 '24 12:08 FalacerSelene

Claude suggested this:

unsigned int generate_seed() {
    unsigned int seed = (unsigned int)time(NULL);
    seed ^= (unsigned int)clock();
    seed ^= (unsigned int)getpid();
    
    struct timespec ts;
    if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) {
        seed ^= (unsigned int)ts.tv_nsec;
    }
    
    return seed;
}

WDYS?

I don't think we gain from mixing 3 different time-based values (time(), clock() and clock_gettime()) - that still gives only time-based uniqueness. So I'd probably just take clock_gettime()'s nanoseconds and forget about time() and clock() in that case, because it's incredibly unlikely that two processes call that in the same ns.

However, clock_getres() might indicate the resolution isn't really to the nanosecond. Since we don't know the resolution of the clock across systems that sipp might run on, I thought it was better to grab other sources of uniqueness (PID and hostname).

But a suggestion like this would almost definitely solve my problem too :)

Sounds good. So can you implement it?

orgads avatar Aug 16 '24 11:08 orgads

Sounds good. So can you implement it?

Yep, updated to XOR with the nanosecond value too :)

FalacerSelene avatar Aug 19 '24 19:08 FalacerSelene

Any idea why the test fails?

orgads avatar Sep 08 '24 12:09 orgads

@jeannotlanglois ?

orgads avatar Sep 15 '24 17:09 orgads

Rebased and it passed. Merging.

Thanks for your persistence @FalacerSelene!

orgads avatar Sep 15 '24 18:09 orgads