Here is my guess at the meaning of it all that appears to work: #include <stdio.h> #include <stdlib.h> #include <fcntl.h> int nRandom; struct random_data randomdataState; char szBufferState[1024]; int main(int argc, char ** argv) { int n; int fd=open("/dev/urandom", O_RDONLY); if(fd<1) { perror("unable to open /dev/urandom"); return 1; } read(fd, szBufferState, sizeof(szBufferState)); close(fd); initstate_r(*((int *)szBufferState), (szBufferState+sizeof(int)), sizeof(szBufferState)-sizeof(int), &randomdataState); for(n=0;n<2048;n++) { random_r(&randomdataState, &nRandom); printf("%d\n", nRandom); } return (0); }
Ok. I tested it and worked. Thanks a lot. You seems to be a "C guru" or similar. GUAU! I have implemented your way random_r() function insime my cpu-test 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); initstate_r(*((int *)szBufferState), (szBufferState+sizeof(int)), sizeof(szBufferState)-sizeof(int), randomdataState); #else #endif } /* int main(int argc, char ** argv) { */ int main() { int i, r, numero_ciclos, numero_ciclosM; clock_t start, end; char* buf; struct random_data randomdataState; /* Se inicializa el generador de numeros aleatorios */ #ifdef linux randomize(&randomdataState); #else randomize(); #endif start = clock(); /* Se reserva 0.1 Gb de memoria */ buf=malloc(100*1024*1024); end = clock(); printf("Reservado 0.1 Gb de memoria en %.3f s.\n", (double)(end - start)/CLOCKS_PER_SEC); start = clock(); /* Se escribe en 0.1 Gb de memoria */ for(i=0; i<100*1024*1024; i++) { buf[i]='0'; } end = clock(); printf("Escritura sobre 0.1 Gb de memoria en %.3f s.\n", (double)(end - start)/CLOCKS_PER_SEC); numero_ciclos = 10000000; numero_ciclosM = numero_ciclos / 1E6; start = clock(); for(i=0; i<numero_ciclos; i++) { r = rand(); } end = clock(); printf("%d M de rand() en %.3f s. (ejemplo.: %d)\n", numero_ciclosM, (double)(end - start)/CLOCKS_PER_SEC, r); start = clock(); for(i=0; i<numero_ciclos; i++) { r = sqrt(i); } end = clock(); printf("%d M de sqrt(i) en %.3f s. (ejemplo.: %d)\n", numero_ciclosM, (double)(end - start)/CLOCKS_PER_SEC, r); start = clock(); for(i=0; i<numero_ciclos; i++) { r = log(i); } end = clock(); printf("%d M de log(i) en %.3f s. (ejemplo.: %d)\n", numero_ciclosM, (double)(end - start)/CLOCKS_PER_SEC, r); start = clock(); for(i=0; i<numero_ciclos; i++) { r = log10(i); } end = clock(); printf("%d M de log10(i) en %.3f s. (ejemplo.: %d)\n", numero_ciclosM, (double)(end - start)/CLOCKS_PER_SEC, r); #ifdef linux start = clock(); for(i=0; i<numero_ciclos; i++) { r = random(); } end = clock(); printf("LINUX: %d M de random() en %.3f s. (ejemplo.: %d)\n", numero_ciclosM, (double)(end - start)/CLOCKS_PER_SEC, r); start = clock(); for(i=0; i<numero_ciclos; i++) { random_r(&randomdataState, &r); } end = clock(); printf("LINUX: %d M de random_r() en %.3f s. (ejemplo.: %d)\n", numero_ciclosM, (double)(end - start)/CLOCKS_PER_SEC, r); start = clock(); for(i=0; i<numero_ciclos; i++) { r = lrand48(); } end = clock(); printf("LINUX: %d M de lrand48() en %.3f s. (ejemplo.: %d)\n", numero_ciclosM, (double)(end - start)/CLOCKS_PER_SEC, r); #else #endif return (0); } ### test-cpu-2.c (the end) ######################################## I have compiled it this way: gcc test-cpu-2.c -o randr-test-cpu-2 -lm -W -Wall -pedantic -O0 I explain later why "-O0". The result is this: # ./randr-test-cpu-2 Reservado 0.1 Gb de memoria en 0.010 s. Escritura sobre 0.1 Gb de memoria en 0.610 s. 10 M de rand() en 46.950 s. (ejemplo.: 1551429474) 10 M de sqrt(i) en 0.240 s. (ejemplo.: 3162) 10 M de log(i) en 0.820 s. (ejemplo.: 16) 10 M de log10(i) en 0.810 s. (ejemplo.: 6) LINUX: 10 M de random() en 38.720 s. (ejemplo.: 146139182) LINUX: 10 M de random_r() en 19.370 s. (ejemplo.: 495480852) LINUX: 10 M de lrand48() en 31.600 s. (ejemplo.: 451810414) 19 seconds is not a good result! I have compiled the same code on an Opteron 64 bits: # gcc test-cpu-2.c -o randr-test-cpu-2 -lm -W -Wall -pedantic -O0 -static # file randr-test-cpu-2 randr-test-cpu-2: ELF 64-bit LSB executable, AMD x86-64, version 1 (SYSV), for GNU/Linux 2.4.0, statically linked, not stripped # ./randr-test-cpu-2 Reservado 0.1 Gb de memoria en 0.000 s. Escritura sobre 0.1 Gb de memoria en 0.720 s. 10 M de rand() en 0.140 s. (ejemplo.: 2146669435) 10 M de sqrt(i) en 0.200 s. (ejemplo.: 3162) 10 M de log(i) en 1.090 s. (ejemplo.: 16) 10 M de log10(i) en 1.230 s. (ejemplo.: 6) LINUX: 10 M de random() en 0.130 s. (ejemplo.: 1324087262) LINUX: 10 M de random_r() en 0.070 s. (ejemplo.: 539283702) LINUX: 10 M de lrand48() en 0.150 s. (ejemplo.: 1823489204) 0.070 seconds is a good result. I have also compiled ir on an Intel Pentium 4 @ 2.40GHz: # gcc test-cpu-2.c -o randr-test-cpu-2 -lm -W -Wall -pedantic -O0 # file randr-test-cpu-2 randr-test-cpu-2: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.2.5, dynamically linked (uses shared libs), not stripped # ./randr-test-cpu-2 Reservado 0.1 Gb de memoria en 0.000 s. Escritura sobre 0.1 Gb de memoria en 0.600 s. 10 M de rand() en 0.420 s. (ejemplo.: 422740983) 10 M de sqrt(i) en 0.660 s. (ejemplo.: 3162) 10 M de log(i) en 1.300 s. (ejemplo.: 16) 10 M de log10(i) en 1.200 s. (ejemplo.: 6) LINUX: 10 M de random() en 0.330 s. (ejemplo.: 870228159) LINUX: 10 M de random_r() en 0.190 s. (ejemplo.: 2081863344) LINUX: 10 M de lrand48() en 0.600 s. (ejemplo.: 119398373) 0.190 seconds is also a good result. In last system, when compiling statically, results become a bit better: # gcc test-cpu-2.c -o randr-test-cpu-2 -lm -W -Wall -pedantic -O0 -static # file randr-test-cpu-2 randr-test-cpu-2: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.2.5, statically linked, not stripped # ./randr-test-cpu-2 Reservado 0.1 Gb de memoria en 0.000 s. Escritura sobre 0.1 Gb de memoria en 0.590 s. 10 M de rand() en 0.270 s. (ejemplo.: 2033397145) 10 M de sqrt(i) en 0.800 s. (ejemplo.: 3162) 10 M de log(i) en 1.540 s. (ejemplo.: 16) 10 M de log10(i) en 1.470 s. (ejemplo.: 6) LINUX: 10 M de random() en 0.260 s. (ejemplo.: 819752714) LINUX: 10 M de random_r() en 0.170 s. (ejemplo.: 28223623) LINUX: 10 M de lrand48() en 0.640 s. (ejemplo.: 1765781247) Conclusion: random_r() function seems to suffer the same bug/problem than rand() standard function. Right? Oddity: initstate_r() function seems to throgh very easily a "Segmentation Fault" error when not compiling with "-O0" flag on certain systems. My opteron and my PIV @ 3Ghz are affected, while my PIV@xxxxxx not. I will appreciate any comments/similar experiencies. Any idea to continue testings? Thanks sincerely!