как измерить скорость проца? зы: знаю, что через rdtsc, но не всегда работает на pentium4. кто знает - помогите исходником на асме, плз!
RamMerLabs Как ты меряешь? Самый ламерский способ (аля Delphi): t0 = rdtsc Sleep(1000) t1 = rdtsc speed = t1 - t0 How can I tell CPU speed?
меряю так: Код (Text): long GetCpuFrequency() { DWORD dwPriorityClass = ::GetPriorityClass(::GetCurrentProcess()); DWORD dwThreadPriority = ::GetThreadPriority(::GetCurrentThread()); ::SetPriorityClass(::GetCurrentProcess(), REALTIME_PRIORITY_CLASS); ::SetThreadPriority(::GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL); ::Sleep(1); LARGE_INTEGER FR, C1, C2; if (! ::QueryPerformanceFrequency(&FR)) return 0; ::QueryPerformanceCounter(&C1); C2.QuadPart = C1.QuadPart; INT64 T1, T2; while (C2.LowPart == C1.LowPart) { ::QueryPerformanceCounter(&C1); __asm { rdtsc mov dword ptr [T1+0], eax mov dword ptr [T1+4], edx } } __asm mov esi, 200000 repeat: __asm { xor eax, eax xor ebx, ebx xor ecx, ecx xor edx, edx cpuid sub esi, 1 jg repeat } ::QueryPerformanceCounter(&C2); __asm { rdtsc mov dword ptr [T2+0], eax mov dword ptr [T2+4], edx } ::SetPriorityClass(::GetCurrentProcess(), dwPriorityClass); ::SetThreadPriority(::GetCurrentThread(), dwThreadPriority); ::Sleep(1); return (long) double((T2 - T1) * double(FR.QuadPart) / double(C2.QuadPart - C1.QuadPart)); }
RamMerLabs Я уже сказал, что использовать Sleep() - это ламерский способ, хотя более-менее рабочий, если использовать задержки > 1s. Можно в цикле вызывать GetSystemTime вместо Sleep(1), но это не намного лучше. В той статье описаны более продвинутые способы, но под win32 в 3м колце они, конечно, не работают. ЗЫ: Совсем забыл! timeBeginPeriod(1) перед вызовом Sleep повышает точность задержки, о чём в форуме уже неоднократно упоминал S_T_A_S_
можно через DMI вот дока со стандартом h++p://www.dmtf.org/standards/published_documents/DSP0134.pdf там читается 65кб памяти с 000F0000h по 000FFFFFh и парсится SMBIOS структуры согласно доки для справки класс 04 Processor Information offset 16h.
Quantum Если замерять "истинный" интервал по QueryPerformance, то и Sleep(X) сойдет Если почистить код RamMerLabs от непонятного мусора, то Код (Text): f rq 1 c1 rq 1 c2 rq 1 tsc rq 1 invoke QueryPerformanceFrequency,f invoke QueryPerformanceCounter,c1 rdtsc mov dword[tsc],eax mov dword[tsc+4],edx invoke Sleep,100 rdtsc sub eax,dword[tsc] sbb edx,dword[tsc+4] mov dword[tsc],eax mov dword[tsc+4],edx invoke QueryPerformanceCounter,c2 fild qword[tsc] fild qword[f] fild qword[c2] fild qword[c1] fsubp fdivp fmulp fistp qword[tsc] С реал-тайм приоритетом дает вполне приемлемую точность на уровне 10^(-5) PS: А точнее наверное и невозможно из-за нестабильности частоты проца
тут на С++ взято с h++p://crystalmark.info/ файл CrystalCPUID48Src.zip там многа тонкостей есть в сорсах...
>> как измерить скорость проца? т.е. тактовую частоту? Код (Text): inline unsigned __int64 GetCycleCount(void) { _asm { _emit 0x0F; _emit 0x31; } } unsigned __int64 GetCPUSpeed(void) { unsigned __int64 startcycle, speed, num, num2; do { startcycle = GetCycleCount(); Sleep(1000); speed = ((GetCycleCount() - startcycle) / 1000000); } while (speed > 1000000); num = speed % 100; num2 = 100; if (num < 80) num2 = 75; if (num < 71) num2 = 66; if (num < 55) num2 = 50; if (num < 38) num2 = 33; if (num < 30) num2 = 25; if (num < 10) num2 = 0; speed = (speed-num)+num2; return speed; } зы: код не мой, но вроде работает
leo Обычно точности до 1й десятой гигагерца достаточно, imho, хотя устовие критичности времени измерения натакивает на мысль, что задача решается в не совсем стандартных условиях, но автор, видимо, так и не откроет нам тайну. Cr4sh Это что-то новое Цепочка if'ов в конце, видимо, для округления.
khv_test DMI - не точная вещь. Особенно что косается процессора и его частоты, многии на это жалуются.