[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

Re: Extremely poor performance crunching random numbers under PIV-FC5



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 2 4Ghz not. I will appreciate any comments/similar experiencies.

Any idea to continue testings?

Thanks sincerely!


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]