Re: pgbench - add pseudo-random permutation function

Fabien COELHO <coelho@cri.ensmp.fr>

From: Fabien COELHO <coelho@cri.ensmp.fr>
To: Dean Rasheed <dean.a.rasheed@gmail.com>
Cc: Alvaro Herrera <alvherre@2ndquadrant.com>, Thomas Munro <thomas.munro@gmail.com>, David Steele <david@pgmasters.net>, Peter Eisentraut <peter.eisentraut@2ndquadrant.com>, Tomas Vondra <tomas.vondra@2ndquadrant.com>, Hironobu SUZUKI <hironobu@interdb.jp>, PostgreSQL Hackers <pgsql-hackers@lists.postgresql.org>
Date: 2021-03-31T17:53:24Z
Lists: pgsql-hackers

Commits

Same data as JSON: GET /api/v1/messages/:b64id/commits the thread's linked commits as JSON, with link sources. API reference →
  1. pgbench: Function to generate random permutations.

  2. Add basic support for using the POPCNT and SSE4.2s LZCNT opcodes

  3. Further improve code for probing the availability of ARM CRC instructions.

Hello Dean,

> OK, attached is an update making this change and simplifying the rotate 
> code, which hopefully just leaves the question of what (if anything) to 
> do with pg_erand48().

Yep. While looking at it, I have some doubts on this part:

  m = (uint64) (pg_erand48(random_state.xseed) * (mask + 1)) | 1;
  r = (uint64) (pg_erand48(random_state.xseed) * (mask + 1));
  r = (uint64) (pg_erand48(random_state.xseed) * size);

I do not understand why the random values are multiplied by anything in 
the first place…

This one looks like a no-op :

    r = (uint64) (pg_erand48(random_state.xseed) * size);
    v = (v + r) % size;

    v = (v + r) % size
      = (v + rand * size) % size
      =? (v % size + rand * size % size) % size
      =? (v % size + 0) % size
      = v % size
      = v

I'm also skeptical about this one:

    r = (uint64) (pg_erand48(random_state.xseed) * (mask + 1));
    if (v <= mask)
       v = ((v * m) ^ r) & mask;

    v = ((v * m) ^ r) & mask
      = ((v * m) ^ r) % (mask+1)
      = ((v * m) ^ (rand * (mask+1))) % (mask+1)
      =? ((v * m) % (mask+1)) ^ (rand * (mask+1) % (mask+1))
      =? ((v * m) % (mask+1)) ^ (0)
      = (v * m) & mask

Or possibly I'm missing something obvious and I'm wrong with my 
arithmetic?

-- 
Fabien.