Prev: _tcstok_s not tokenizing as expected
Next: Win XP Pro Boot to desktop (rather than user logon screen)
From: Franz Bachler on 7 Jul 2010 15:10 Hello, this is part of a CPU-Speed-Detection Program: #ifdef __BORLANDC__ void getRdtsc( UINT64* pResult ) { _asm { db 0x0F db 0x31 mov ebx, pResult mov [ebx], eax mov [ebx+4], edx } } UINT64 rdtsc(void) { UINT64 result; getRdtsc( &result ); return result; } #else // Visual Studio inline UINT64 rdtsc(void) { _asm __emit 0x0F _asm __emit 0x31 } #endif How to encode this in MinGW? Greetings, Franz -- Franz Bachler, A-3250 Wieselburg E-Mail: fraba (at) gmx.at Homepage: http://members.aon.at/fraba or http://home.pages.at/fraba
From: Alf P. Steinbach /Usenet on 7 Jul 2010 18:46 * Franz Bachler, on 07.07.2010 21:10: > Hello, > > this is part of a CPU-Speed-Detection Program: > > #ifdef __BORLANDC__ > void getRdtsc( UINT64* pResult ) > { > _asm > { > db 0x0F > db 0x31 > mov ebx, pResult > mov [ebx], eax > mov [ebx+4], edx > } > } > > UINT64 rdtsc(void) > { > UINT64 result; > getRdtsc(&result ); > return result; > } > #else // Visual Studio > inline UINT64 rdtsc(void) > { > _asm __emit 0x0F > _asm __emit 0x31 > } > #endif > > How to encode this in MinGW? You can use the -S option to check the generated assembly. MinGW g++ supports both Intel and AT&T assembly syntax, and this is a bit problematic. The default is AT&T (your examples above are Intel syntax). You can specify the syntax using option -masm=intel or -masm=att, I think it was. There's also an assembler directive for switching syntax. I don't recall but google it if you need it. Essentially you just declare the function, like extern "C" void UINT64 rtdsc(); and immediately follow that with an 'asm' directive. It needs each line of assembly as a string literal, IIRC. Good luck! - Alf -- blog at <url: http://alfps.wordpress.com>
From: Franz Bachler on 9 Jul 2010 11:47 here we go: if you compile it with -Wall you'll get the following warning: cpumingw.c: In function `rdtsc': cpumingw.c:15: warning: control reaches end of non-void function but it works fine /* MinGW * * gcc -o cpuspeed.exe -s cpuspeed.c -masm=intel -mwindows */ #include <windows.h> UINT64 rdtsc(void) { asm ( ".byte 0x0F\n" ".byte 0x31\n" ); } typedef LRESULT (WINAPI * CALLNTPOWERINFORMATION)(POWER_INFORMATION_LEVEL, PVOID, ULONG, PVOID, ULONG); typedef struct _PROCESSOR_POWER_INFORMATION { ULONG Number; ULONG MaxMhz; ULONG CurrentMhz; ULONG MhzLimit; ULONG MaxIdleState; ULONG CurrentIdleState; } PROCESSOR_POWER_INFORMATION, *PPROCESSOR_POWER_INFORMATION; typedef LONG NTSTATUS; UINT_PTR GetCpuSpeed(VOID) { PROCESSOR_POWER_INFORMATION ppi; CALLNTPOWERINFORMATION pfn; LARGE_INTEGER liFreq,li1,li2; OSVERSIONINFO osvi; HINSTANCE hDll; NTSTATUS stat; UINT_PTR uSpeed; UINT64 timestamp; HANDLE hThread; int nPriority; ZeroMemory(&osvi, sizeof(OSVERSIONINFO)); osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); GetVersionEx(&osvi); // not for Windows NT4 and 9x if (osvi.dwMajorVersion>=5) { ZeroMemory(&ppi, sizeof(ppi)); stat = ERROR_CALL_NOT_IMPLEMENTED; if (NULL != (hDll = LoadLibrary(TEXT("powrprof.dll")))) { if (NULL != (pfn = (CALLNTPOWERINFORMATION)GetProcAddress(hDll, "CallNtPowerInformation"))) { stat = pfn(ProcessorInformation, NULL, 0, &ppi, sizeof(ppi)); } FreeLibrary(hDll); } if (ERROR_SUCCESS == stat) return(ppi.CurrentMhz); } hThread = GetCurrentThread(); nPriority = GetThreadPriority(hThread); QueryPerformanceFrequency(&liFreq); liFreq.QuadPart /= 10; SetThreadPriority(hThread, THREAD_PRIORITY_HIGHEST); timestamp = rdtsc(); QueryPerformanceCounter(&li1); do { QueryPerformanceCounter(&li2); } while ((li2.QuadPart - li1.QuadPart) < liFreq.QuadPart); uSpeed = (UINT_PTR)((rdtsc() - timestamp) / 100000); SetThreadPriority(hThread, nPriority); return(uSpeed); } int main(void) { TCHAR szSpeed[128]; wsprintf(szSpeed, TEXT("CPU-Speed: ~%u MHz \n"), GetCpuSpeed()); MessageBox(NULL, szSpeed, TEXT(" Info "), MB_OK); return(0); }
From: Franz Bachler on 16 Jul 2010 07:24 Hello, and the next problem & solution for MinGW: The FPU is very slow, up to 3times slower than as with other compilers. I've found this page http://www.network-theory.co.uk/docs/gccintro/gccintro_70.html and created the following code based of this information: #if !defined (__BORLANDC__) && !defined (_MSC_VER) // use double-precision rounding for MinGW unsigned short cw=0x027F; asm("fldcw %0" : : "m" (*&cw)); // this works only if cw is a global variable // asm("fldcw _cw"); #endif Put this in the beginning of main() and look: the FPU is fast now. Greetings, Franz
From: Alf P. Steinbach /Usenet on 16 Jul 2010 08:12
* Franz Bachler, on 16.07.2010 13:24: > Hello, > > and the next problem& solution for MinGW: > > The FPU is very slow, up to 3times slower than as with other compilers. > I've found this page > > http://www.network-theory.co.uk/docs/gccintro/gccintro_70.html > > and created the following code based of this information: > > #if !defined (__BORLANDC__)&& !defined (_MSC_VER) > // use double-precision rounding for MinGW > unsigned short cw=0x027F; > asm("fldcw %0" : : "m" (*&cw)); > // this works only if cw is a global variable > // asm("fldcw _cw"); > #endif > > Put this in the beginning of main() and look: the FPU is fast now. Oh, interesting. Probably there is some gcc runtime lib function for setting the rounding mode. Cheers, - Alf -- blog at <url: http://alfps.wordpress.com> |