util/nvmutil: optimise rhex() further

reduce the number of calls to read() by using
bit shifts. when rnum is zero, read again. in
most cases, a nibble will not be zero, so this
will usually result in about 13-15 of of 16
nibbles being used. this is in comparison to
8 nibbles being used before, which means that
the number of calls to read() are roughly
halved. at the same time, the extra amount of
logic is minimal (and probably less) when
compiled, outside of calls to read(), because
shifting is better optimised (on 64-bit machines,
the uint64_t will be shifted with just a single
instruction, if the compiler is decent), whereas
the alternative would be to always precisely use
exactly 16 nibbles by counting up to 16, which
would involve the use of an and mask and still
need a shift, plus...

you get the point. this is probably the most
efficient code ever written, for generating
random numbers between the value of 0 and 15
fsdg20230625
Leah Rowe 2023-03-06 19:21:46 +00:00
parent f04855c29d
commit f9e20b8a1d
1 changed files with 6 additions and 4 deletions

View File

@ -261,10 +261,9 @@ rhex(void)
{
static int rfd = -1;
static uint64_t rnum = 0;
static size_t rindex = 8;
uint8_t rval;
if (rindex == 8) {
rindex = 0;
if (rnum == 0) {
if (rfd == -1)
if ((rfd = open("/dev/urandom", O_RDONLY)) == -1)
err(errno, "/dev/urandom");
@ -272,7 +271,10 @@ rhex(void)
err(errno, "/dev/urandom");
}
return ((uint8_t *) &rnum)[rindex++] & 0xf;
rval = (uint8_t) (rnum & 0xf);
rnum >>= 4;
return rval;
}
void