SIPp / sipp

The SIPp testing tool
https://sipp.readthedocs.io
Other
926 stars 385 forks source link

Initialize srand with hostname and PID #738

Closed FalacerSelene closed 2 months ago

FalacerSelene commented 3 months ago

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!

orgads commented 3 months ago

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?

FalacerSelene commented 3 months ago

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 :)

orgads commented 3 months ago

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?

FalacerSelene commented 3 months ago

Sounds good. So can you implement it?

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

orgads commented 2 months ago

Any idea why the test fails?

orgads commented 2 months ago

@jeannotlanglois ?

orgads commented 2 months ago

Rebased and it passed. Merging.

Thanks for your persistence @FalacerSelene!