Commit 5b7e0367 authored by Tom Lane's avatar Tom Lane

Avoid unnecessary precision loss for pgbench's --rate target.

It's fairly silly to truncate the throttle_delay to integer when the only
math we ever do with it requires converting back to double.  Furthermore,
given that people are starting to complain about restrictions like only
supporting 1K client connections, I don't think we're very far away from
situations where the precision loss matters.  As the code stood, for
example, there's no difference between --rate 100001 and --rate 111111;
both get converted to throttle_delay = 9.  Somebody trying to run 100
threads and have each one dispatch around 1K TPS would find this lack of
precision rather surprising, especially since the required per-thread
delays are around 1ms, well within the timing precision of modern systems.
parent 64171b32
...@@ -169,7 +169,7 @@ double sample_rate = 0.0; ...@@ -169,7 +169,7 @@ double sample_rate = 0.0;
* When threads are throttled to a given rate limit, this is the target delay * When threads are throttled to a given rate limit, this is the target delay
* to reach that rate in usec. 0 is the default and means no throttling. * to reach that rate in usec. 0 is the default and means no throttling.
*/ */
int64 throttle_delay = 0; double throttle_delay = 0;
/* /*
* Transactions which take longer than this limit (in usec) are counted as * Transactions which take longer than this limit (in usec) are counted as
...@@ -826,9 +826,12 @@ getGaussianRand(TState *thread, int64 min, int64 max, double parameter) ...@@ -826,9 +826,12 @@ getGaussianRand(TState *thread, int64 min, int64 max, double parameter)
/* /*
* random number generator: generate a value, such that the series of values * random number generator: generate a value, such that the series of values
* will approximate a Poisson distribution centered on the given value. * will approximate a Poisson distribution centered on the given value.
*
* Individual results are rounded to integers, though the center value need
* not be one.
*/ */
static int64 static int64
getPoissonRand(TState *thread, int64 center) getPoissonRand(TState *thread, double center)
{ {
/* /*
* Use inverse transform sampling to generate a value > 0, such that the * Use inverse transform sampling to generate a value > 0, such that the
...@@ -839,7 +842,7 @@ getPoissonRand(TState *thread, int64 center) ...@@ -839,7 +842,7 @@ getPoissonRand(TState *thread, int64 center)
/* erand in [0, 1), uniform in (0, 1] */ /* erand in [0, 1), uniform in (0, 1] */
uniform = 1.0 - pg_erand48(thread->random_state); uniform = 1.0 - pg_erand48(thread->random_state);
return (int64) (-log(uniform) * ((double) center) + 0.5); return (int64) (-log(uniform) * center + 0.5);
} }
/* helper function for getZipfianRand */ /* helper function for getZipfianRand */
...@@ -5114,8 +5117,8 @@ main(int argc, char **argv) ...@@ -5114,8 +5117,8 @@ main(int argc, char **argv)
fprintf(stderr, "invalid rate limit: \"%s\"\n", optarg); fprintf(stderr, "invalid rate limit: \"%s\"\n", optarg);
exit(1); exit(1);
} }
/* Invert rate limit into a time offset */ /* Invert rate limit into per-transaction delay in usec */
throttle_delay = (int64) (1000000.0 / throttle_value); throttle_delay = 1000000.0 / throttle_value;
} }
break; break;
case 'L': case 'L':
...@@ -5239,7 +5242,11 @@ main(int argc, char **argv) ...@@ -5239,7 +5242,11 @@ main(int argc, char **argv)
if (nthreads > nclients) if (nthreads > nclients)
nthreads = nclients; nthreads = nclients;
/* compute a per thread delay */ /*
* Convert throttle_delay to a per-thread delay time. Note that this
* might be a fractional number of usec, but that's OK, since it's just
* the center of a Poisson distribution of delays.
*/
throttle_delay *= nthreads; throttle_delay *= nthreads;
if (argc > optind) if (argc > optind)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment