]> granicus.if.org Git - postgresql/commitdiff
Lift the limitation that # of clients must be a multiple of # of threads
authorHeikki Linnakangas <heikki.linnakangas@iki.fi>
Fri, 3 Jul 2015 07:45:40 +0000 (10:45 +0300)
committerHeikki Linnakangas <heikki.linnakangas@iki.fi>
Fri, 3 Jul 2015 07:45:40 +0000 (10:45 +0300)
Fabien Coelho

doc/src/sgml/ref/pgbench.sgml
src/bin/pgbench/pgbench.c

index a8085463a5e33c906c2d645e55db6edd14314a28..2517a3abe7fae41f0d8ae5ee0698d5fad82bec58 100644 (file)
@@ -326,8 +326,7 @@ pgbench <optional> <replaceable>options</> </optional> <replaceable>dbname</>
        <para>
         Number of worker threads within <application>pgbench</application>.
         Using more than one thread can be helpful on multi-CPU machines.
-        The number of clients must be a multiple of the number of threads,
-        since each thread is given the same number of client sessions to manage.
+        Clients are distributed as evenly as possible among available threads.
         Default is 1.
        </para>
       </listitem>
index 2c3e3650c8a307dd3bf034c1d5c8141ea8fae396..74c3371c21d34cfd9abacb84a54d5ced67ed5462 100644 (file)
@@ -2819,6 +2819,7 @@ main(int argc, char **argv)
        int64           latency_late = 0;
 
        int                     i;
+       int                     nclients_dealt;
 
 #ifdef HAVE_GETRLIMIT
        struct rlimit rlim;
@@ -3114,6 +3115,14 @@ main(int argc, char **argv)
                }
        }
 
+       /*
+        * Don't need more threads than there are clients.  (This is not merely an
+        * optimization; throttle_delay is calculated incorrectly below if some
+        * threads have no clients assigned to them.)
+        */
+       if (nthreads > nclients)
+               nthreads = nclients;
+
        /* compute a per thread delay */
        throttle_delay *= nthreads;
 
@@ -3153,12 +3162,6 @@ main(int argc, char **argv)
        if (nxacts <= 0 && duration <= 0)
                nxacts = DEFAULT_NXACTS;
 
-       if (nclients % nthreads != 0)
-       {
-               fprintf(stderr, "number of clients (%d) must be a multiple of number of threads (%d)\n", nclients, nthreads);
-               exit(1);
-       }
-
        /* --sampling-rate may be used only with -l */
        if (sample_rate > 0.0 && !use_log)
        {
@@ -3359,19 +3362,24 @@ main(int argc, char **argv)
 
        /* set up thread data structures */
        threads = (TState *) pg_malloc(sizeof(TState) * nthreads);
+       nclients_dealt = 0;
+
        for (i = 0; i < nthreads; i++)
        {
                TState     *thread = &threads[i];
 
                thread->tid = i;
-               thread->state = &state[nclients / nthreads * i];
-               thread->nstate = nclients / nthreads;
+               thread->state = &state[nclients_dealt];
+               thread->nstate =
+                       (nclients - nclients_dealt + nthreads - i - 1) / (nthreads - i);
                thread->random_state[0] = random();
                thread->random_state[1] = random();
                thread->random_state[2] = random();
                thread->throttle_latency_skipped = 0;
                thread->latency_late = 0;
 
+               nclients_dealt += thread->nstate;
+
                if (is_latencies)
                {
                        /* Reserve memory for the thread to store per-command latencies */
@@ -3395,6 +3403,9 @@ main(int argc, char **argv)
                }
        }
 
+       /* all clients must be assigned to a thread */
+       Assert(nclients_dealt == nclients);
+
        /* get start up time */
        INSTR_TIME_SET_CURRENT(start_time);