#pragma warning(disable:4996) #include #include #include #include #include #include "mytypes.h" #include "tpool.h" #include "bitlock.h" typedef struct { U64 sem; U32 n; union { U64 version; struct { U16 counts[4]; }; }; } ARGS; void worker0( void *arg ) { ARGS *v = (ARGS*)arg; volatile U16 dummy[ 4 ]; U32 i; wait( &v->sem, 0, 1 ); for( i = 0; i < v->n; ++i ) ++dummy[ rand() % 4 ]; return; } void worker1( void *arg ) { ARGS *v = (ARGS*)arg; U32 i; wait( &v->sem, 0, 1 ); for( i = 0; i < v->n; ++i ) _InterlockedIncrement16( &v->counts[ rand() % 4 ] ); return; } void worker2( void *arg ) { ARGS *v = (ARGS*)arg; U32 i; wait( &v->sem, 0, 1 ); for( i = 0; i < v->n; ++i ) ++v->counts[ rand() % 4 ]; return; } int main( int argc, char **argv ) { U32 workers = argc > 1 ? atoi( argv[ 1 ] ) : 4; U32 n = argc > 2 ? atoi( argv[ 2 ] ) : 100000000; ARGS a; HANDLE pool; LARGE_INTEGER freq, start, stop; QueryPerformanceFrequency( &freq ); a.sem = 0ull; a.n = n; a.version = 0ull; lock( &a.sem, 0, 0 ); pool = tpool( &worker0, workers, &a ); QueryPerformanceCounter( &start ); unlock( &a.sem, 0 ); WaitForSingleObject( pool, INFINITE ); QueryPerformanceCounter( &stop ); printf( "%4u threads x %10u iterations of normal increment non-shared took %14.9f seconds\n", workers, n, (double)( stop.QuadPart - start.QuadPart ) / freq.QuadPart ); a.sem = 0ull; a.n = n; a.version = 0ull; lock( &a.sem, 0, 0 ); pool = tpool( &worker1, workers, &a ); QueryPerformanceCounter( &start ); unlock( &a.sem, 0 ); WaitForSingleObject( pool, INFINITE ); QueryPerformanceCounter( &stop ); printf( "%4u threads x %10u iterations of interlockedIncrement16() took %14.9f seconds\n", workers, n, (double)( stop.QuadPart - start.QuadPart ) / freq.QuadPart ); a.sem = 0ull; a.n = n; a.version = 0ull; lock( &a.sem, 0, 0 ); pool = tpool( &worker2, workers, &a ); QueryPerformanceCounter( &start ); unlock( &a.sem, 0 ); WaitForSingleObject( pool, INFINITE ); QueryPerformanceCounter( &stop ); printf( "%4u threads x %10u iterations of normal increment shared took %14.9f seconds\n", workers, n, (double)( stop.QuadPart - start.QuadPart ) / freq.QuadPart ); return 0; } #### C:\test>for %t in (1,2,4,16,63,255) do @interlock %t 10000000 1 threads x 10000000 iterations of normal increment non-shared took 0.269178904 seconds 1 threads x 10000000 iterations of interlockedIncrement16() took 0.501895073 seconds 1 threads x 10000000 iterations of normal increment shared took 0.327297743 seconds 2 threads x 10000000 iterations of normal increment non-shared took 0.268091336 seconds 2 threads x 10000000 iterations of interlockedIncrement16() took 1.407993195 seconds 2 threads x 10000000 iterations of normal increment shared took 1.072541343 seconds 4 threads x 10000000 iterations of normal increment non-shared took 0.331791610 seconds 4 threads x 10000000 iterations of interlockedIncrement16() took 4.877205343 seconds 4 threads x 10000000 iterations of normal increment shared took 4.260821138 seconds 16 threads x 10000000 iterations of normal increment non-shared took 1.172022981 seconds 16 threads x 10000000 iterations of interlockedIncrement16() took 19.987548697 seconds 16 threads x 10000000 iterations of normal increment shared took 17.639230964 seconds 63 threads x 10000000 iterations of normal increment non-shared took 4.423643228 seconds 63 threads x 10000000 iterations of interlockedIncrement16() took 78.821976536 seconds 63 threads x 10000000 iterations of normal increment shared took 69.604602540 seconds 255 threads x 10000000 iterations of normal increment non-shared took 17.773377901 seconds 255 threads x 10000000 iterations of interlockedIncrement16() took 320.197832965 seconds 255 threads x 10000000 iterations of normal increment shared took 282.370355450 seconds C:\test>interlock 1023 1000000 1023 threads x 1000000 iterations of normal increment non-shared took 7.115383938 seconds 1023 threads x 1000000 iterations of interlockedIncrement16() took 127.386793294 seconds 1023 threads x 1000000 iterations of normal increment shared took 112.850957873 seconds