Extremely poor performance crunching random numbers under PIV-FC5

Jakub Jelinek jakub at redhat.com
Fri May 19 09:54:55 UTC 2006


On Fri, May 19, 2006 at 11:17:37AM +0200, BankHacker wrote:
> code. Here it is the full source code:
> 
> ### test-cpu-2.c ##################################################
> 	#include <stdio.h>
> 	#include <stdlib.h>
> 	#include <math.h>
> 	#include <time.h>
> 	#include <string.h>
> 	#include <fcntl.h>
> 	
> 	#ifdef linux
> 	inline void randomize(struct random_data *randomdataState) {
> 	#else
> 	inline void randomize() {
> 	#endif
> 	    time_t seconds;
> 	#ifdef linux
> 		char szBufferState[1024];
> 		extern int read();
> 		extern int close();
> 		int fd;
> 	#else
> 	#endif
> 	
> 		time(&seconds);
> 		srand((unsigned int) seconds);
> 	
> 	#ifdef linux
> 	    /* Se inicializa el generador especial de numeros aleatorios */
> 	    srand48((unsigned int) seconds);
> 	
> 		fd=open("/dev/urandom", O_RDONLY);
> 		if(fd<1) { perror("unable to open /dev/urandom"); /*return 
> 		1;*/ }
> 	
> 		read(fd, szBufferState, sizeof(szBufferState));
> 		close(fd);
> 	

You need to make sure *randomdataState is zero initialized before calling
initstate_r for the first time.  So, e.g. add
memset (randomdataState, 0, sizeof (*randomdataState));
here.

> 		initstate_r(*((int *)szBufferState), 
> 		(szBufferState+sizeof(int)),
> sizeof(szBufferState)-sizeof(int), randomdataState);

Filling szBufferState with random data is completely unnecessary,
initstate_r overwrites it anyway.
If you want to initialize randomdataState the same way srandom(seconds);
does, don't open /dev/urandom at all and just do:
static int buf[32];
memset (randomdataState, 0, sizeof (*randomdataState));
initstate_r (seconds, (char *) buf, 128, &randomdataState);

Note that:
a) you should make sure the buffer is at least 4 bytes aligned
b) the buffer must be available during all random_r/srandom_r calls
with that random_data struct, until you initstate_r to another buffer.
Which your testcase doesn't fulfil, szBufferState is a local variable
that gets out of scope as soon as randomize returns, at which point
it can be reused for anything else.  So, either you make it static storage
duration variable, or pass it from main the same way how you pass struct
random_data.

	Jakub




More information about the fedora-list mailing list