Может кто-нибудь подскажет как точно оперделить частоту камня этот код даёт не точный результат (даже с realtime приоритетом) Code (Text): rdtsc mov TimerLow, EAX mov TimerHigh, EDX push 1000 call Sleep rdtsc sub EAX, TimerLow sbb EDX, TimerHigh EAX=CPU freq а CPUId и прочие проги дают очень точный результат, возможно они не вычисляют, а считывают частоту (FSB, множители), но откуда? З. Ы. Толковой доки на эту тему я не нашёл (наверно плохо искал).
Sleep отпускает процессор и с большой вероятностью вгоняет его в hlt, а современные звери в простое имеют тенденцию сбрасывать частоту (ну а че зря напрягаться ). Кстати, CPU-Z это отражает. И с чего ты взял, что частота должна быть очень точной?
Просто интересно откуда SiSoft sandra, CPU-Z берут FSB и множитель (соотв. получают freq с точностью до 1 Mhz, а моя прога +-20 Mhz , что не есть гуд), может из MSR. Дебаггить CPU-Z и разбираться в нём нет желания.
mr_Infern0 Для повышения точности достаточно замерить реальное время Sleep(100) по QueryPerformanceXXX. См. пример
Вполне юзабельно, но всё-же может кто знает где лежит значение FSB, multiplier. Я имею ввиду что-то типа: Code (Text): mov DX, PORT_CPU_PARAMETERS mov EAX, XX out DX, EAX in EAX, DX ; EAX=FSB или Code (Text): mov EСX, MSR_REG_CPU_PARAMETERS rdmsr ; EAX=FSB
Некторые проги тупо из реестра берут %) [HKEY_LOCAL_MACHINE\HARDWARE\DESCRIPTION\System\CentralProcessor\0]
censored Всё чё там есть система получает ч-з cpuid, rdtsc, а это не рулит. Да и вообще читать из реестра это по ламерски.
mr_Infern0 а) убери Sleep, вставь нормальную функцию типа GetTickCount; б) выполняй цикл (неважно какой, главное, выполняй) хотя бы ~0.1 сек; в) считай кол-во таков с помощью rdtsc; г) измеряй время выполнения через GetTickCount; д) вычисляй результат, округляя результат до целых MHz;
kaspersky Удивительно от Тебя такое слышать :о GetTickCount выдает результат с погрешностью 10-15 мс, соответственно для измеряемого интервала ~0.1 сек точность измерения будет ~10^(-1), а для 1 сек соотв-но ~10^(-2), что собс-но и получил mr_Infern0 при Sleep(1000) - "моя прога +-20 Mhz " Поэтому величину интервала нужно замерять точнее с помощью QueryPerformance (см. пост #4)
Неужели нет человеческого способа узнать частоту CPU (не вычислять её) Где-то она должна лежать в виде числа (IMHO БИОС при запуске ни rdtsc, ни QueryPerfomance не юзает).
частотомер попробуй, все люди так измеряют частоту! а ссылку на обсуждение тебе уже дали http://www.wasm.ru/forum/viewtopic.php?pid=146061#p146061 там нормально определяется частота, единственная трабла - полученный способ не работает на x86-64 процах.
mr_Infern0 В качестве числа, а вернее строки можно получить из самого процессора, она в нем зашита. Команда CPUID. А реальная частота может отличаться. Меряют таймером. Причем в старых процессорах где CPUID не было частоту тоже определяли по таймеру. Но делали округление. С выборкой из таблицы. Еще можно через множитель и частоту шины определить. Для этого по флагом определяется тип процессора. И далее в зависимости от процессора. БИОС, чего только не использует.
SMBIOS то что нужно, не понял тока как его в protected mode использовать, при попытке чтения 000F0000 - 000FFFFF - BSOD в GDT штоль лезть надо?
0x000F0000 - 0x000FFFFF физические адреса, а у тебя они интерпретируются (скорее всего) как виртуальные, что приводит к #PF
Ustus <Sleep отпускает процессор и с большой вероятностью вгоняет его в hlt, а современные звери в простое > Вообще то просто отключает поток от планировщика на время указанное в параметре. Вот код, считающий такты процессора, запускать в КМ. Code (Text): DWORD GetCPUClock() // возможность измерить частоту до 4 Ггц { DWORD T_eax_; DWORD T_edx_; _asm { pushad pushfd cli // застопорить прерывания mov al,0x0b out 0x70,al in al,0x71 mov bl,al mov al,0x0b out 0x70,al mov al,bl or al,00000100b //время в бинарном формате out 0x71,al _R_: mov al,0 out 0x70,al in al,0x71 cmp al,0x38 // не более 58 секунд jge _R_ // если больше или равняется, то ждать нуля mov bl,al __T: mov al,0 out 0x70,al in al,0x71 cmp al,bl jle __T mov bl,al // начало чистой секунды rdtsc // считали текущее состояние счётчика тактов mov dword ptr T_eax_,eax mov dword ptr T_edx_,edx __RR: mov al,0 out 0x70,al in al,0x71 cmp al,bl je __RR rdtsc // новое значение счётчика тактов // теперь подсчитываем такты процессора sti sub eax, T_eax_ sub edx, T_edx_ add eax,edx mov dword ptr T_eax_,eax mov al,0x0b out 0x70,al in al,0x71 mov bl,al mov al,0x0b out 0x70,al mov al,bl and al,11111011b // выдавать время в формате BCD out 0x71,al popfd popad } return T_eax_; // наиточнейшая частота процессора }
mr_Infern0 <И чё нужно делать, чтоб из физической памяти читать?> Эти адреса уже промаплены. Тебе просто нужно найти их.