Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "globals.h"
- #include <stdio.h>
- #include <stdlib.h>
- #include <stdint.h>
- #include <intrin.h>
- #include <string>
- #include <windows.h>
- #include <algorithm>
- #include <map>
- #include <unordered_map>
- using namespace std;
- namespace perf_map_ {
- typedef unsigned long long uint64;
- #define SIZE_OF_STAT 10
- #define BOUND_OF_LOOP 10
- const int core = 2;
- void processor() {
- int mask = 1 << core;
- DWORD_PTR pa, sa;
- GetProcessAffinityMask( GetCurrentProcess(), &pa, &sa );
- if( !(mask & pa) ) {
- puts( "error0" ); printf( "%d %d\n", mask, pa ); system( "PAUSE" ); return;
- }
- //
- if( !SetPriorityClass( GetCurrentProcess(), REALTIME_PRIORITY_CLASS ) ) {
- puts( "error1a" ); system( "PAUSE" ); return;
- }
- if( !SetProcessAffinityMask( GetCurrentProcess(), mask ) ) {
- puts( "error1b" ); system( "PAUSE" ); return;
- }
- if( !SetThreadPriority( GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL ) ) {
- puts( "error2a" ); system( "PAUSE" ); return;
- }
- if( !SetThreadAffinityMask( GetCurrentThread(), mask ) ) {
- puts( "error2b" ); system( "PAUSE" ); return;
- }
- Sleep( 1 );
- printf( "core %d\n", GetCurrentProcessorNumber() );
- }
- #define _CYCLES_START \
- __asm CPUID \
- __asm RDTSC \
- __asm mov cycles_high, edx \
- __asm mov cycles_low, eax \
- #define _CYCLES_END \
- __asm RDTSCP \
- __asm mov cycles_high1, edx \
- __asm mov cycles_low1, eax \
- __asm CPUID \
- std::map<int, string> map_obj;
- std::unordered_map<int, string> umap_obj;
- const int N = 10;
- void test_init()
- {
- for( int k=0; k < N; ++k ) {
- //int x = i + (100 * k);
- map_obj[k] = "aha";// to_string( x );
- }
- for( int k=0; k < N; ++k ) {
- //int x = i + (100 * k);
- umap_obj[k] = "aha";//to_string( x );
- }
- }
- void test_destroy() {
- map_obj.clear();
- umap_obj.clear();
- }
- //
- void test_map( int i ) {
- for( int k=0; k < 10; ++k )
- string x = map_obj[k];
- }
- void test_unordered_map( int i ) {
- for( int k=0; k < 10; ++k )
- string x = umap_obj[k];
- }
- void inline Filltimes( uint64 **times, void( *pre_func )(), void( *func )(int), void( *post_func )() ) {
- unsigned long flags;
- int i, j;
- uint64 start, end;
- unsigned cycles_low, cycles_high=0, cycles_low1, cycles_high1=0;
- volatile int variable = 0;
- pre_func();
- func( 0 );
- post_func();
- _CYCLES_START
- _CYCLES_END
- pre_func();
- func( 0 );
- post_func();
- _CYCLES_START
- _CYCLES_END
- _CYCLES_START
- _CYCLES_END
- start = (((uint64)cycles_high << 32) | cycles_low);
- end = (((uint64)cycles_high1 << 32) | cycles_low1);
- uint64 diff = end - start;
- for( j=0; j < BOUND_OF_LOOP; j++ ) {
- for( i =0; i < SIZE_OF_STAT; i++ ) {
- variable = 0;
- pre_func();
- _CYCLES_START
- func( i );
- _CYCLES_END
- post_func();
- start = (((uint64)cycles_high << 32) | cycles_low);
- end = (((uint64)cycles_high1 << 32) | cycles_low1);
- if( diff + start > end ) times[j][i]=1;
- else times[j][i] = end - start;// -diff;
- }
- }
- }
- uint64 var_calc( uint64 *inputs, int size )
- {
- int i;
- uint64 acc = 0, previous = 0, temp_var = 0;
- for( i=0; i < size; i++ ) {
- if( acc < previous ) goto overflow;
- previous = acc;
- acc += inputs[i];
- }
- acc = acc * acc;
- if( acc < previous ) goto overflow;
- previous = 0;
- for( i=0; i < size; i++ ) {
- if( temp_var < previous ) goto overflow;
- previous = temp_var;
- temp_var+= (inputs[i] * inputs[i]);
- }
- temp_var = temp_var * size;
- if( temp_var < previous ) goto overflow;
- temp_var =(temp_var - acc) / (((uint64)(size))*((uint64)(size)));
- return (temp_var);
- overflow:
- return -EINVAL;
- }
- uint64 ** init_times()
- {
- uint64 **times;
- int j = 0, k = 0;
- times = (uint64 **)malloc( BOUND_OF_LOOP * sizeof( uint64* ) );
- if( !times ) {
- return nullptr;
- }
- for( j=0; j < BOUND_OF_LOOP; j++ ) {
- times[j] = (uint64 *)malloc( SIZE_OF_STAT * sizeof( uint64 ) );
- if( !times[j] ) {
- for( k=0; k < j; k++ )
- free( times[k] );
- return nullptr;
- }
- }
- return times;
- }
- void do_test_set( void( *pre_func )(), void( *func )(int), void( *post_func )() ) {
- int i = 0, j = 0, spurious = 0, k =0;
- uint64 **times;
- uint64 *variances;
- uint64 *min_values;
- uint64 max_dev = 0, min_time = 0, max_time = 0, prev_min =0, tot_var=0, max_dev_all=0, var_of_vars=0, var_of_mins=0;
- times= init_times();
- if( !times ) return;
- variances = (uint64 *)malloc( BOUND_OF_LOOP * sizeof( uint64 ) );
- if( !variances ) return;
- min_values = (uint64 *)malloc( BOUND_OF_LOOP * sizeof( uint64 ) );
- if( !min_values ) return;
- Filltimes( times, pre_func, func, post_func );
- for( j=0; j < BOUND_OF_LOOP; j++ )
- {
- max_dev = 0;
- min_time = 0;
- max_time = 0;
- for( i =0; i < SIZE_OF_STAT; i++ ) {
- if( (min_time == 0) || (min_time > times[j][i]) )
- min_time = times[j][i];
- if( max_time < times[j][i] )
- max_time = times[j][i];
- }
- max_dev = max_time - min_time;
- min_values[j] = min_time;
- if( (prev_min != 0) && (prev_min > min_time) )
- spurious++;
- if( max_dev > max_dev_all )
- max_dev_all = max_dev;
- variances[j] = var_calc( times[j], SIZE_OF_STAT );
- tot_var += variances[j];
- printf( "\nj:%d >> variance: %I64u; max_deviation: %I64u ;min time: %I64u", j, variances[j], max_dev, min_time );
- prev_min = min_time;
- }
- var_of_vars = var_calc( variances, BOUND_OF_LOOP );
- var_of_mins = var_calc( min_values, BOUND_OF_LOOP );
- printf( "\n total number of spurious min values = %d", spurious );
- printf( "\n total variance = %I64u", (tot_var / BOUND_OF_LOOP) );
- printf( "\n absolute max deviation = %I64u", max_dev_all );
- printf( "\n variance of variances = %I64u", var_of_vars );
- printf( "\n variance of minimum values = %I64u", var_of_mins );
- printf( "\n" );
- for( j=0; j < BOUND_OF_LOOP; j++ ) {
- free( times[j] );
- }
- free( times );
- free( variances );
- free( min_values );
- }
- void test()
- {
- processor();
- do_test_set( test_init, test_map, test_destroy );
- do_test_set( test_init, test_unordered_map, test_destroy );
- }
- };
- void perf_map() {
- perf_map_::test();
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement