#include #include #include #include #define FIBER_COUNT 50000000 #define FIVEK 5000 #define TENK 10000 #define ONEHUNK 100000 #define ONEMIL 1000000 #define MEMORY_TEST 200000000 VOID _fastcall MemToReg ( IN ULONG Count, IN PULONG Address ); VOID _fastcall RegToMem ( IN ULONG Count, IN PULONG Address ); typedef struct _FLS_VALUE { DWORD Value1; DWORD Value2; } FLS_VALUE, *PFLS_VALUE; // // Define local types. // typedef struct _PERFINFO { DWORD StartTime; DWORD StopTime; LPSTR Title; DWORD Iterations; } PERFINFO, *PPERFINFO; VOID FinishBenchMark ( IN PPERFINFO PerfInfo ) { DWORD ContextSwitches; DWORD Duration; DWORD Performance; // // Print results and announce end of test. // PerfInfo->StopTime = GetTickCount(); Duration = PerfInfo->StopTime - PerfInfo->StartTime; printf(" Test time in milliseconds %d\n", Duration); printf(" Number of iterations %d\n", PerfInfo->Iterations); Performance = (DWORD)((ULONG64)PerfInfo->Iterations * 1000 / Duration); printf(" Iterations per second %d\n", Performance); printf("*** End of Test ***\n\n"); return; } VOID StartBenchMark ( IN PCHAR Title, IN DWORD Iterations, IN PPERFINFO PerfInfo ) { // // Announce start of test and the number of iterations. // printf("*** Start of test ***\n %s\n", Title); PerfInfo->Title = Title; PerfInfo->Iterations = Iterations; PerfInfo->StartTime = GetTickCount(); return; } VOID VqTest( VOID ) { PERFINFO PerfInfo; int i; PVOID Pv; DWORD dw; MEMORY_BASIC_INFORMATION BasicInfo; // // Reserve 64k and commit one page // Pv = VirtualAlloc(NULL,65536,MEM_RESERVE,PAGE_READWRITE); if ( !Pv ) { printf("Virtual Alloc(a) Failed %d\n",GetLastError()); ExitProcess(1); } Pv = VirtualAlloc(Pv,4096,MEM_COMMIT,PAGE_READWRITE); if ( !Pv ) { printf("Virtual Alloc(b) Failed %d\n",GetLastError()); ExitProcess(1); } SetPriorityClass(GetCurrentProcess(),REALTIME_PRIORITY_CLASS); StartBenchMark( "Virtual Query Test", 5*ONEHUNK, &PerfInfo ); for ( i=0;i<5*ONEHUNK;i++) { dw = VirtualQuery(Pv,&BasicInfo,sizeof(BasicInfo)); } FinishBenchMark(&PerfInfo); SetPriorityClass(GetCurrentProcess(),NORMAL_PRIORITY_CLASS); } VOID MulDivTest( VOID ) { PERFINFO PerfInfo; int i; SetPriorityClass(GetCurrentProcess(),REALTIME_PRIORITY_CLASS); StartBenchMark( "MulDiv(4,2,5) Test", 5*ONEMIL, &PerfInfo ); for ( i=0;i<5*ONEMIL;i++) { MulDiv(4,2,5); } FinishBenchMark(&PerfInfo); StartBenchMark( "MulDiv(-4,2,5) Test", 5*ONEMIL, &PerfInfo ); for ( i=0;i<5*ONEMIL;i++) { MulDiv(-4,2,5); } FinishBenchMark(&PerfInfo); StartBenchMark( "MulDiv(4,-2,5) Test", 5*ONEMIL, &PerfInfo ); for ( i=0;i<5*ONEMIL;i++) { MulDiv(4,-2,5); } FinishBenchMark(&PerfInfo); StartBenchMark( "MulDiv(-4,-2,5) Test", 5*ONEMIL, &PerfInfo ); for ( i=0;i<5*ONEMIL;i++) { MulDiv(-4,-2,5); } FinishBenchMark(&PerfInfo); StartBenchMark( "MulDiv(0x10,0x400,0) Test", 5*ONEMIL, &PerfInfo ); for ( i=0;i<5*ONEMIL;i++) { MulDiv(0x10,0x400,0); } FinishBenchMark(&PerfInfo); StartBenchMark( "MulDiv(0x10,0x40000000,2) Test", 5*ONEMIL, &PerfInfo ); for ( i=0;i<5*ONEMIL;i++) { MulDiv(0x10,0x40000000,2); } FinishBenchMark(&PerfInfo); SetPriorityClass(GetCurrentProcess(),NORMAL_PRIORITY_CLASS); } VOID GfaTest( LPSTR Str ) { PERFINFO PerfInfo; int i; StartBenchMark( "GetFileAttributes Test", FIVEK, &PerfInfo ); for ( i=0;iValue1, (PVOID)Value->Value1) == FALSE) { printf("fiber 1 - set index %d failed\n", Value->Value1); } if (FlsSetValue(Value->Value2, (PVOID)Value->Value2) == FALSE) { printf("fiber 1 - set index %d failed\n", Value->Value2); } Name = strtok("fiber 1", ":"); printf("%s starting loop\n", Name); for(;;) { if (FlsGetValue(Value->Value1) != (PVOID)Value->Value1) { printf("fiber 1 - get value at index % d return wrong value %d\n", Value->Value1, FlsGetValue(Value->Value1)); } if (FlsGetValue(Value->Value2) != (PVOID)Value->Value2) { printf("fiber 1 - get value at index % d return wrong value %d\n", Value->Value2, FlsGetValue(Value->Value2)); } SwitchToFiber0(); } } VOID SwitchToFiber1 ( VOID ) { SwitchToFiber(Fibers[1]); return; } VOID FiberRoutine0( LPVOID lpParameter ) { PFLS_VALUE Value; PERFINFO PerfInfo; int i; PCHAR Name; StartBenchMark( "Fiber Switch Test", FIBER_COUNT, &PerfInfo ); Value = GetFiberData(); if (FlsSetValue(Value->Value1, (PVOID)Value->Value1) == FALSE) { printf("fiber 0 - set index %d failed\n", Value->Value1); } if (FlsSetValue(Value->Value2, (PVOID)Value->Value2) == FALSE) { printf("fiber 0 - set index %d failed\n", Value->Value2); } Name = strtok("Fiber 0", ":"); printf("%s starting loop\n", Name); for ( i = 0; i < FIBER_COUNT; i++) { if (FlsGetValue(Value->Value1) != (PVOID)Value->Value1) { printf("fiber 0 - get value at index % d return wrong value %d\n", Value->Value1, FlsGetValue(Value->Value1)); } if (FlsGetValue(Value->Value2) != (PVOID)Value->Value2) { printf("fiber 0 - get value at index % d return wrong value %d\n", Value->Value2, FlsGetValue(Value->Value2)); } SwitchToFiber1(); } FinishBenchMark(&PerfInfo); } VOID WINAPI FibCallback ( PVOID Data ) { if (((DWORD)Data != 0) && ((DWORD)Data != FlsValue1.Value1) && ((DWORD)Data != FlsValue1.Value2) && ((DWORD)Data != FlsValue2.Value1) && ((DWORD)Data != FlsValue2.Value2)) { printf("callback routine incorrectly called for data %d\n", (DWORD)Data); } return; } VOID FibTst( DWORD Flags ) { Fibers[0] = ConvertThreadToFiberEx((LPVOID)&FlsValue1, Flags); Fibers[1] = CreateFiberEx(0, 0, Flags, FiberRoutine1, (LPVOID)&FlsValue2); FlsValue1.Value1 = FlsAlloc(&FibCallback); FlsValue1.Value2 = FlsAlloc(&FibCallback); FlsValue2.Value1 = FlsAlloc(&FibCallback); FlsValue2.Value2 = FlsAlloc(&FibCallback); FiberRoutine0((LPVOID)1); if (ConvertFiberToThread() == FALSE) { printf("fiber convertion to thread failed\n"); } DeleteFiber(Fibers[1]); if (FlsFree(FlsValue1.Value1) == FALSE) { printf("thread 0 unable to free index %d\n", FlsValue1.Value1); } if (FlsFree(FlsValue1.Value2) == FALSE) { printf("thread 0 unable to free index %d\n", FlsValue1.Value2); } if (FlsFree(FlsValue2.Value1) == FALSE) { printf("thread 0 unable to free index %d\n", FlsValue2.Value1); } if (FlsFree(FlsValue2.Value2) == FALSE) { printf("thread 0 unable to free index %d\n", FlsValue2.Value2); } return; } VOID MemoryTest ( VOID ) { PULONG Address; CHAR Buffer[512]; ULONG Count; PERFINFO PerfInfo; // // Memory to register - aligned. // Address = (PULONG)(((ULONG)(&Buffer[128]) + 3) & ~3); StartBenchMark("Memory To Register Aligned Test", MEMORY_TEST, &PerfInfo); MemToReg(MEMORY_TEST, Address); FinishBenchMark(&PerfInfo); // // Memory to register - unaligned within cache line // Address = (PULONG)((((ULONG)(&Buffer[256]) + 127) & ~127) + 1); StartBenchMark("Memory To Register Unaligned Within Cache Line Test", MEMORY_TEST, &PerfInfo); MemToReg(MEMORY_TEST, Address); FinishBenchMark(&PerfInfo); // // Memory to register - unaligned across cache line // Address = (PULONG)((((ULONG)(&Buffer[256]) + 127) & ~127) - 1); StartBenchMark("Memory To Register Unaligned Across Cache Line Test", MEMORY_TEST / 2, &PerfInfo); MemToReg(MEMORY_TEST, Address); FinishBenchMark(&PerfInfo); // // Register to memory - aligned. // Address = (PULONG)(((ULONG)(&Buffer[256]) + 3) & ~3); StartBenchMark("Register To Memory Aligned Test", MEMORY_TEST, &PerfInfo); RegToMem(MEMORY_TEST, Address); FinishBenchMark(&PerfInfo); // // Register to Memory - unaligned within cache line // Address = (PULONG)((((ULONG)(&Buffer[256]) + 127) & ~127) + 1); StartBenchMark("Register To Memory Unaligned Within Cache Line Test", MEMORY_TEST, &PerfInfo); RegToMem(MEMORY_TEST, Address); FinishBenchMark(&PerfInfo); // // Register to Memory - unaligned across cache line // Address = (PULONG)((((ULONG)(&Buffer[256]) + 127) & ~127) - 1); StartBenchMark("Register To Memory Unaligned Across Cache Line Test", MEMORY_TEST / 2, &PerfInfo); RegToMem(MEMORY_TEST, Address); FinishBenchMark(&PerfInfo); return; } DWORD _cdecl main( int argc, char *argv[], char *envp[] ) { // VqTest(); // MulDivTest(); // GmhTest(); // if ( argc > 1 ) { // GfaTest(argv[1]); // } FibTst(0); FibTst(FIBER_FLAG_FLOAT_SWITCH); // MemoryTest(); ExitThread(0); return 0; }