Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.15.235.196] |
|
Сообщ.
#1
,
|
|
|
Имхо замерять время выполнения всей программы наоборот не имеет смысла - если снимать профайл, то с отдельных её участков. Если вместо связки QPC/QPF использовать RDTSC/CPU.freq, то это позволит вычислять время вплоть до нано/секунд, т.е. даже единичные инструкции (например узнать, насколько в цикле лучше DEC,чем LOOP).
Сейчас-же, всё зависит от частоты таймера QPerfFrequency(), макс.значение которого всего 14 MHz (и то, если задействован HPET, а так 3). Поэтому логичней, взять за основу сразу частоту CPU 1..3 GHz, и его счётчик тактов TSC. Бонусом, не помешала-бы и сериализация на входе/выходе через инструкцию LFENCE.. т.е. учитывать спекулятивное выполнение кода процессором. А вообще, для таких случаев в составе Ntdll.dll имеется набор спец.функций NtCreateProfile(), которые в качестве метронома используют таймер локального контролёра LAPIC. Этот таймер работает на частоте шины FSB/DMI (100..200 MHz), а значит и он уступает связке RDTSC+CPUfreq. Однако эти функции точились индусами специально для профайлеров, так-что сбрасывать их со-счетов было-бы глупо. Эта тема была разделена из темы "КТЗ!" |
Сообщ.
#2
,
|
|
|
Цитата core-i7 @ Поэтому логичней, взять за основу сразу частоту CPU 1..3 GHz, и его счётчик тактов TSC. Бонусом, не помешала-бы и сериализация на входе/выходе через инструкцию LFENCE.. т.е. учитывать спекулятивное выполнение кода процессором. А можно пример кода, как это запрограммить? |
Сообщ.
#3
,
|
|
|
..что-то в этом роде:
;====== Частота процессора mov ecx,2 @@: push ecx lfence rdtsc push eax invoke Sleep,500 rdtsc pop ebx sub eax,ebx mov ebx,500000 cdq div ebx pop ecx dec ecx jnz @b mov [cpuFreq],eax ; запомнить cinvoke printf,<10,' CPU freq..: %d MHz',0>,eax ;====== Частота таймера invoke QueryPerformanceFrequency,qpf mov eax,[qpf] mov ebx,1000000 cdq div ebx cinvoke printf,<10,' Timer freq: %d.%d MHz',0>,eax,edx ;====== Погрешность = 2 инструкции: сериализация LFENCE, и чтение TSC lfence rdtsc push eax lfence rdtsc pop ebx sub eax,ebx mov [fix],eax ; запомнить ;*************************** ; Профайлер ;*************************** lfence rdtsc push eax ;<----- Сюда вставляем профилируемые инструкции lfence rdtsc pop ebx sub eax,ebx sub eax,[fix] push eax fild dword[esp] ; такты fidiv [cpuFreq] ; разделить на частоту процессора fstp [fpuBuff] ; время в нано/секундах pop eax cinvoke printf,<10,'%u Takt = %.3f Micro/sec',0>,\ eax, dword[fpuBuff], dword[fpuBuff+4] Здесь я вывел частоту таймера QPF, чтобы сравнить её с частотой процессора. Если QPF возвратит 3.5 MHz, значит система использует в качестве основного ACPI-таймер (3.579545 MHz), если больше 10 MHz - HPET (в идеале 14). В любом случае, QPF в десятки раз отстаёт от процессора. |
Сообщ.
#4
,
|
|
|
core-i7, привет, Тимур
Хм... я всегда думал, что QPC тоже использует использует rdtsc или rdtscp (по крайней мере, эта инструкция там есть) и сдвигает результат на 10 бит, но QPF выдал 10 млн, что наводит на размышления. Зачем же тогда там эти rdtsc? Т.к. lfence ставит барьер только на чтение и не гарантирует, что перед rdtsc влезет одна из последующих инструкций, я бы делал так всё же: mfence rdtsc mfence Вот хорошая дока по этой теме: http://www.mkurnosov.net/uploads/Main/mkur...-rdtsc-2014.pdf А есть ещё инструкция rdpmc, которая как раз для профайлинга предназначена, но она сложнее в использовании и не всегда нужна. К тому же, она привилегированная (в винде, в линуксе, видимо, тоже), нужно драйвер писать, хотя у Агнера Фога уже есть: https://www.agner.org/optimize/#testp Добавлено Можно ещё приоритет потока выставлять по максимуму, кстати. |
Сообщ.
#5
,
|
|
|
Женя, салам!
Цитата Jin X @ но QPF выдал 10 млн, что наводит на размышления. Зачем же тогда там эти rdtsc? 10 илн, это значит 10 MHz чтоли? (т.к. там в наносек блоках) У меня на буке тоже не подымается выше 10-ти, хотя это HPET и частота его 14 MHz. а rdtsc наверное там для какой-нибудь калибровки. |
Сообщ.
#6
,
|
|
|
[cut по просьбе автора]
Лично мне вот интересно, предложения core-i7 смогут ли улучшить точность С++ шного std::chrono::high_resolution_clock? И чуйка мне подсказывает "несомненно" (я всегда надеюсь на лучшее, прогрессивное и спортивное)! [cut по просьбе автора] Цитата Jin X @ Хм... я всегда думал, что QPC тоже использует использует rdtsc или rdtscp В качестве антиоффтопика ... когда я увидел код от core-i7, сразу побежал интересоваться незнакомыми мне командами Статья-за-статьей, статья-за-статьей ... и у меня есть ответ на твой вопрос (частично). А именно! QPC не точнее кода от core-i7 лишь потому, что там - API, и под капотом у которого стопицот индусов, которых погоняют 10 брахманов (даже если они используют rdtsc или rdtscp). А у core-i7 в примере - только инструкции камня. Ну это чисто мое ИМХО. Мнений конечно дохрена, но я пока вот такое выбрал за истину. |
Сообщ.
#7
,
|
|
|
Цитата core-i7 @ QFP выдаёт частоту, т.е. 10 млн - это 10 МГц. При чём тут наносекунды? 10 илн, это значит 10 MHz чтоли? (т.к. там в наносек блоках) |
Сообщ.
#8
,
|
|
|
Скрытый текст Эх ... удалил такое искреннее сообщение от себя За два года модерства - расслабился, потерял чуйку! Добавлено Ну мож быть ... тебе виднее - но я заметил именно профилирование. Но спорить не хочу совсем - мне диалог дальнейший интересен. Мое мнение ... та-сяк ... слушать интереснее, особенно если собеседники плотно в теме. |
Сообщ.
#9
,
|
|
|
Цитата JoeUser @ Не понимаю, о чём ты?Эх ... удалил такое искреннее сообщение от себя За два года модерства - расслабился, потерял чуйку! Если надо, можно найти сообщение (отредактированное, удалённое). Но с этим лучше в Л.С., чтобы не засорять обсуждение. Цитата JoeUser @ Не в заголовке суть, а в великих речах, глаголящих истину Ну мож быть ... тебе виднее - но я заметил именно профилирование. |
Сообщ.
#10
,
|
|
|
Что любопытно, XP (виртуальная) выдаёт 3ГГц, а 7ка уже 10МГц
Добавлено core-i7, поправь-таки код. Частота путает уменьшаемое и вычитаемое, все замеры путают знаковую и беззнаковую арифметику, а целочисленную арифметику замени на 64-битную, ибо странно наблюдать отрицательные Micro/sec |
Сообщ.
#11
,
|
|
|
Цитата Qraizer @ В 98 вообще 1.19 МГц Что любопытно, XP (виртуальная) выдаёт 3ГГц, а 7ка уже 10МГц Там таймер 8254 используется |
Сообщ.
#12
,
|
|
|
Подкину дровишек.
1) Для виртуализации TSC сохраняется в контексте процесса и после загружается обратно. Причем виндоус использует это всегда. 2) Цитата В давние времена да. е RDTSC+CPUfreq. Однако эти функции точились индусами специально для профайлеров, Суть в том что если делать x64 программы то там эта комбинация плавает в отрицательные области. А х32- программах индусы всё же сделали что'бы они не плавали. 3) Цитата таймер локального контролёра LAPIC. Этот таймер работает на частоте шины FSB/DMI (100..200 MHz), Там не 100 Мгц, а частота RDTSC. Только младшие биты 4-5 бит они не контролируют. 4) Для профилирования есть PerformanceCounter нужен драйвер. У интела есть IntelPerformanceCounterMonitor-PCM-V2.10 нужно только GUI или API прекрутить. |
Сообщ.
#13
,
|
|
|
Цитата Qraizer @ Как вариант:core-i7, поправь-таки код Скрытый текст format PE Console 4.0 entry start include 'win32axp.inc' ;-- CODE SECTION ------------------------------------------------------------------------------------------------------- macro ReadTSC { mfence rdtsc mfence } .code start: invoke SetThreadPriority, -2, THREAD_PRIORITY_TIME_CRITICAL ;====== Частота процессора ReadTSC push eax push edx invoke Sleep,1000 ReadTSC pop ecx pop ebx sub eax,ebx sbb edx,ecx push edx push eax fild qword[esp] add esp,8 fidiv [N1M] fistp [cpuFreq] cinvoke printf,<10,' CPU freq: %d MHz',0>,[cpuFreq] ;====== Частота таймера invoke QueryPerformanceFrequency,qpf fild [qpf] fidiv [N1M] fstp [fpuBuff] cinvoke printf,<10,'Timer freq: %f MHz',0>,dword[fpuBuff],dword[fpuBuff+4] ;====== Погрешность = 2 инструкции: сериализация LFENCE, и чтение TSC ReadTSC push eax ReadTSC pop ebx sub eax,ebx mov [fix],eax ; запомнить ;*************************** ; Профайлер ;*************************** ReadTSC push eax ;<----- Сюда вставляем профилируемые инструкции ReadTSC pop ebx sub eax,ebx sub eax,[fix] push eax fild dword [esp] ; такты fidiv [cpuFreq] ; разделить на частоту процессора fstp [fpuBuff] ; время в микросекундах pop eax cinvoke printf,<10,'%i ticks = %f microsec',0>,\ eax, dword[fpuBuff], dword[fpuBuff+4] cinvoke getch invoke ExitProcess, 0 ;-- DATA SECTION ------------------------------------------------------------------------------------------------------- .data N1M dd 1000000 cpuFreq dd ? fix dd ? qpf dq ? fpuBuff dq ? ;-- IMPORT SECTION ----------------------------------------------------------------------------------------------------- section '.idata' import data readable library kernel32, 'kernel32.dll',\ msvcrt, 'msvcrt.dll' import_kernel32 all_api import msvcrt,\ printf, 'printf',\ getch, '_getch' |
Сообщ.
#14
,
|
|
|
Скрытый текст Цитата Jin X @ Не понимаю, о чём ты? Это и хорошо! 30 гратусов тов. Цельсия в тени меня сводят с ума - и я уже кидаюсь на всех аки собака Баскервили) |
Сообщ.
#15
,
|
|
|
Цитата Jin X @ У меня этот код в виртуальной Win98 показывает время пустого кода минус несколько тысяч тактов, в 10-ке в районе -20 (в среднем), на домашнем около нуля (+/-). Любопытненько, однако...Как вариант И ещё на домашнем частота 3300 измеряется, на вирт. 3700. Хотя всякие там CPU-Z показывают 3700. На самом деле у меня небольшой штатный разгон: 3300 -> 3700. Это что, так Invariant TSC работает? Цитата Pavia @ А если поподробнее? 1) Для виртуализации TSC сохраняется в контексте процесса и после загружается обратно. Причем виндоус использует это всегда. |
Сообщ.
#16
,
|
|
|
Цитата JoeUser @ А именно! QPC не точнее лишь потому, что там - API, не совсем так.. Чтобы получить реальное время, нужно иметь счётчик и частоту, на которой этот счётчик работает. Например если взять счётчик процессора TSC и разделить его не на частоту процессора, а частоту таймера HPET, то получим не правильное время. Именно поэтому пара QPC+QPF должны всегда ходить вместе. Если замерить, сколько раз простучит QPC в течении одной секунды, то непременно получим значение, которое вернёт нам QPF. Это-же касается и пары RDTSC+CPUfreq. Цитата Qraizer @ поправь-таки код. да.. он кривой, т.к. я его набросал на коленке. Спасибо вот Jin X поправил. Цитата Pavia @ А х32- программах индусы всё же сделали что'бы они не плавали. я имел в виду, что индусы точили набор функций NtCreateProfile(), с которыми я кстати так и разобрался до конца. Цитата Pavia @ Там не 100 Мгц, а частота RDTSC. Только младшие биты 4-5 бит они не контролируют. вполне возможно, только эта частота у меня всегда совпадает с физической частотой системной шины, без множителя CPU. Цитата Jin X @ Это что, так Invariant TSC работает? именно так он и работает! На новых чипсетах TSC выделен в отдельный домен, и идёт напрямую от системного клокера, - овер биоса на неё не влияет. Прикреплённый файлtscp.png (9,88 Кбайт, скачиваний: 1027) |
Сообщ.
#17
,
|
|
|
Цитата core-i7 @ А на ВМ проц типа стартует сразу с разогнанной частоты, поэтому и показывает её? овер биоса на неё не влияет Добавлено Цитата core-i7 @ Я в том году поинтереснее код для теста начал писать, но не доделал. Хотя, осталось чуть-чуть.Спасибо вот Jin X поправил. Я вот только думаю, есть ли смысл выравнивать тестовый код по 16 байтам? Как я понял, основная фишка этого выравнивания в том, чтобы весь код попал в один 16-байтный блок. Т.е. если код занимает, скажем, 8 байт (ну или 24), то он может начинаться с любого адреса от 0 до 7 (в младшем полубайте), разницы не будет никакой. update: Вот инфа по этому поводу. Получается, что так и есть. Прикреплённый файлcode_align.png (101,79 Кбайт, скачиваний: 1191) |
Сообщ.
#18
,
|
|
|
Доделал вроде как вполне приличную тестилку скорости кода.
Пока только под 64 бита. format PE64 Console 5.0 include 'win64axp.inc' ;-- CODE SECTION ------------------------------------------------------------------------------------------------------- .code entry: frame ; -1 is handle of current process (GetCurrentProcess), -2 is handle of current thread (GetCurrentThread) invoke SetProcessAffinityMask, -1, 1 ; to aviod CPU migration invoke SetPriorityClass, -1, REALTIME_PRIORITY_CLASS ; available only when running with administrator rights invoke SetThreadPriority, -2, THREAD_PRIORITY_TIME_CRITICAL stdcall SpeedTestInit, -1 stdcall SpeedTestMsg, test1, 'Testing 1...', <' %llu ticks%s',10>, ' (CPU migration is detected)' stdcall SpeedTestMsg, test2, 'Testing 2...', <' %llu ticks%s',10>, ' (CPU migration is detected)' stdcall SpeedTestMsg, test3, 'Testing 3...', <' %llu ticks%s',10>, ' (CPU migration is detected)' invoke SetThreadPriority, -2, THREAD_PRIORITY_NORMAL invoke SetPriorityClass, -1, NORMAL_PRIORITY_CLASS cinvoke printf, 'Press a key to exit...' cinvoke getch invoke ExitProcess, 0 endf align 16 test1: xor eax,eax cpuid ret align 16 test2: mov ecx,65536 @@: dec ecx jnz @B ret align 16 test3: mov ecx,65536 loop $ ret ;-- SPEED TEST PROCEDURES ---------------------------------------------------------------------------------------------- ; Speed-test procedures for Windows x64, v1.00a ; (c) 2020 by Jin X (jin_x@list.ru) SPEEDTEST_REPEATS = 256 ; number of code execution repeats (must be power of two!!!) SPEEDTEST_WARMUPS = 1 shl (bsr SPEEDTEST_REPEATS / 2) ; number of warming-up executions assert SPEEDTEST_WARMUPS >= 0 & SPEEDTEST_REPEATS > 0 & bsf SPEEDTEST_REPEATS = bsr SPEEDTEST_REPEATS ; Initialize speed-test and show message if needed (via printf) ; Parameters: ecx = show message flags: bit 0 - when rdtscp is NOT supported, bit 1 - when invariant TSC is NOT supported, bit 2 - when everything's ok (ecx = -1 - all messages) ; Returns: rax = unsupported feature flags: bit 0 - rdtscp is NOT supported, bit 1 - invariant TSC is NOT supported (eax = 0 - both features are supported) proc SpeedTestInit uses rbx, MsgFlags frame mov r8b,3 ; temp result mov r9d,ecx ; show message flags mov eax,0x80000000 cpuid mov r10d,eax ; max extended cpuid leaf level ; RDTSCP instruction support check mov eax,0x80000001 cmp r10d,eax jb .no_inv ; both features are NOT supported cpuid bt edx,27 ; rdtscp support bit jnc .no_rdtscp and r8b,not 1 ; mark as supported mov [SpeedTestGetTSC],SpeedTestRDTSCP ; use RDTSC instruction .no_rdtscp: ; Invariant TSC support check mov eax,0x80000007 cmp r10d,eax jb .no_inv cpuid bt edx,8 ; invariant TSC support bit jnc .no_inv and r8b,not 2 ; mark as supported .no_inv: mov bl,r8b mov bh,bl ; save result mask test bl,bl setz cl shl cl,2 or bl,cl ; set bit 2 in r8d if both features are supported and bl,r9b ; bit mask for messages ; Messages test bl,1 jz @F cinvoke printf, <"Warning: RDTSCP instruction is not supported, RDTSC will be used instead (CPU migration can't be detected)!", 10> @@: test bl,2 jz @F cinvoke printf, <"Warning: invariant TSC is not supported (results may be inaccurate)!", 10> @@: test bl,4 jz @F cinvoke printf, <"Success: both RDTSCP instruction and invariant TSC are supported.", 10> @@: ; Measure overhead xor eax,eax mov [SpeedTestOverhead],rax stdcall SpeedTest, SpeedTestEmptyFunc ; overhead test mov [SpeedTestOverhead],rax movzx eax,bh ; results ret endf endp ; SpeedTestInit ; Measure procedure speed and show message (via printf) ; Parameters: ; * rcx = proc address ; * rdx = starting message (0 - no message, -1 - 'Testing...' message); ; * r8 = result message (0 - no message, -1 - just a number of ticks and new line), should contain '%llu' for result TSC count and then '%s' (optional) for CPU migration message (specified by r9); ; * r9 = CPU migration message (optional, should be used only is r8 message contains '%s'). ; Returns: rax = TSC count (always positive value), zf = 1 if no CPU migration is occured proc SpeedTestMsg ProcAddr, PreMsg, ResultMsg, MigMsg SpeedTestMsg% = 0 ; turn off parameter count check frame mov [ProcAddr],rcx mov [ResultMsg],r8 mov [MigMsg],r9 ; Starting message test rdx,rdx jz .no_start cmp rdx,-1 jne @F mov rdx,.testing_msg @@: cinvoke printf, '%s', rdx .no_start: ; Test speed stdcall SpeedTest, [ProcAddr] mov [ProcAddr],rax setz byte [PreMsg] ; save zf ; Result message mov r8,.no_message jz @F ; jump if no CPU migration mov r8,[MigMsg] @@: mov rcx,[ResultMsg] test rcx,rcx jz .no_results cmp rcx,-1 jne @F mov rcx,.just_ticks @@: cinvoke printf, rcx, rax, r8 .no_results: ; Return values mov rax,[ProcAddr] dec byte [PreMsg] ; restore zf ret endf .testing_msg db 'Testing...',0 .just_ticks db ' %llu',10 .no_message db 0 endp ; SpeedTestMsg ; Measure procedure speed ; Parameters: rcx = proc address ; Returns: rax = TSC count (always positive value), zf = 1 if no CPU migration is occured proc SpeedTest uses rbx rsi rdi r12 r13 r14 r15, ProcAddr frame mov r12,rcx ; Warming-up calls if SPEEDTEST_WARMUPS > 0 mov esi,SPEEDTEST_WARMUPS @@: stdcall r12 dec esi jnz @B end if ; Main tests cld mov rdi,SpeedTestResults xor r15d,r15d mov esi,SPEEDTEST_REPEATS @@:; invoke SwitchToThread ; try to update thread time slice invoke SpeedTestGetTSC ; get ticks in rax, CPU id in ecx mov r13,rax mov r14d,ecx stdcall r12 ; main call invoke SpeedTestGetTSC ; get ticks in rax, CPU id in ecx sub rax,r13 sub rax,[SpeedTestOverhead] ; result TSC count stosq ; store to SpeedTestResults sub ecx,r14d ; detect CPU migration or r15d,ecx ; migration flag for all tests dec esi jnz @B if SPEEDTEST_REPEATS > 2 ; Sort results mov rcx,SpeedTestResults mov rdx,SPEEDTEST_REPEATS stdcall InsertionSort64 end if ; Calculate average CPU ticks if SPEEDTEST_REPEATS <= 2 mov ecx,SPEEDTEST_REPEATS else mov ecx,SPEEDTEST_REPEATS/2 ; use only 50% of results from array middle (assuming that 25% at the start and end are errors) end if xor eax,eax xor edx,edx @@: add rax,[SpeedTestResults+(SPEEDTEST_REPEATS/4)*8 + rdx*8] ; sum of all relevant results inc edx dec ecx jnz @B if SPEEDTEST_REPEATS > 2 sar rax,bsr (SPEEDTEST_REPEATS/2) ; average value else if SPEEDTEST_REPEATS = 2 sar rax,bsr SPEEDTEST_REPEATS ; average value test rax,rax end if cmovs eax,ecx ; zero result if negative test r15d,r15d ; zf = 1 if no CPU migration is occured ret endf endp ; SpeedTest ; Read TSC via RDTSC [for internal use] ; Returns: rax = current TSC counter value, ecx = 0 (processor id detection is not supported) ; Changes ebx !!! if used SpeedTestRDTSC SpeedTestRDTSC: xor eax,eax ; cpuid execution time may vary depending on eax value cpuid ; serialization xor ecx,ecx rdtsc shl rdx,32 or rax,rdx mfence SpeedTestEmptyFunc: ret end if ; used SpeedTestRDTSC ; Read TSC via RDTSCP [for internal use] ; Returns: rax = current TSC counter value, ecx = processor id if used SpeedTestRDTSCP SpeedTestRDTSCP: rdtscp shl rdx,32 or rax,rdx mfence ret end if ; used SpeedTestRDTSCP if used InsertionSort64 ; Insertion sort of 64-bit elements ; Parameters: rcx = array address, rdx = number of elements InsertionSort64: mov r8d,1 ; start key_index cmp rdx,r8 jle .exit ; jump if number of element <= 1 .loop1: mov rax,[rcx+r8*8] ; key mov r9,r8 ; el_index .loop2: mov r10,[rcx+(r9-1)*8] ; prev_el cmp r10,rax ; prev_el <=> key ? jng @F mov [rcx+r9*8],r10 ; if (prev_el > key) el = prev_el dec r9 ; --el_index jnz .loop2 ; repeat if el_index > 0 @@: mov [rcx+r9*8],rax ; el = key inc r8 ; ++key_index cmp r8,rdx jb .loop1 ; repeat if key_index < number of elements .exit: ret end if ; used InsertionSort64 ;-- DATA SECTION ------------------------------------------------------------------------------------------------------- .data if used SpeedTestInit SpeedTestGetTSC dq SpeedTestRDTSC ; TSC read procedure SpeedTestOverhead rq 1 ; TSC read overhead tick count SpeedTestResults rq SPEEDTEST_REPEATS ; Temporary result array end if ; used SpeedTestInit ;-- IMPORT SECTION ----------------------------------------------------------------------------------------------------- section '.idata' import data readable library kernel32, 'kernel32.dll',\ msvcrt, 'msvcrt.dll' import_kernel32 all_api import msvcrt,\ printf, 'printf',\ getch, '_getch' Прикреплённый файлspeedtest64.fasm (8,73 Кбайт, скачиваний: 739) |
Сообщ.
#19
,
|
|
|
Цитата Jin X @ А на ВМ проц типа стартует сразу с разогнанной частоты, поэтому и показывает её? ..имхо на вирту вообще не нужно делать ставки, поскольку она живёт своей жизнью Цитата Jin X @ Доделал вроде как вполне приличную тестилку скорости кода прикольно получилось - зачёт! |
Сообщ.
#20
,
|
|
|
Цитата core-i7 @ Я там косякнул кое-где (с цифровыми параметрами для SpeedTestMsg) прикольно получилось - зачёт! Сейчас исправил, сообщение обновил |
Сообщ.
#21
,
|
|
|
И снова исправлен косячок, добавленный в результате предыдущего исправления: прога всегда показывала CPU migration
Файлы обновлены. Сообщения были разделены в тему "Определение микроархитектуры CPU" |
Сообщ.
#22
,
|
|
|
core-i7, ты знаешь, всё-таки QPC использует не HPET, даже при значениях QPF = 10 млн.
Я тут почитал кое-что. Во-первых, для HPET нужно идти в ядро, а QPC этого не делает (по крайней мере, у меня на 10-ке точно, да и на 7-ке, насколько я помню, было так же). Во-вторых, он читает RDTSCP и дальше выполняет какие-то хитрые арифметические операции, в результате чего преобразует это значение в QPC-счётчик. Причём, он выполняет не только деление (через умножение), но и зачем-то добавляет какие-то числа, ибо отношение RDTSCP/QPC постепенно растёт. |
Сообщ.
#23
,
|
|
|
Цитата Jin X @ Во-вторых, он читает RDTSCP и дальше выполняет какие-то хитрые арифметические операции тогда QPF должна быть привязана к частоте процессора чтоли? (ведь QPF и QPC работают синхронно) к примеру у меня CPU=1.1 GHz и QPF возвращает 10 MHz, ты говоришь, что у тебя тоже 10 MHz, а частота процессора какая? и почему тогда, если НРЕТ не поддерживается чипсетом, то QPF в аккурат равна частоте ACPI-таймера 3.579545 MHz - где параллель с TSC ??? |
Сообщ.
#24
,
|
|
|
Не исключено, что занижение частоты связано со всякими там Spectre. Хотя и верится несколько с трудом, т.к. занижение QPF выполнено гораздо раньше, чем сообщено о той же Spectre. Ну или о Spectre было уже давно известно, гораздо раньше публикаций.
|
Сообщ.
#25
,
|
|
|
Цитата core-i7 @ Нет.тогда QPF должна быть привязана к частоте процессора чтоли? Как я понял, винда на старте проверяет наличие invariant TSC. Если он присутствует, то вычисляет кол-во циклов в секунду и определяет делитель (обратный множитель). А вот время вызова QPC проверяется выбранный на старте режим (HPET или TSC), и если используется TSC, читает его, добавляет что-то ещё зачем-то и делит на этот делитель, подгоняя таким образом к частоте 10 МГц. Цитата core-i7 @ Подозреваю, что там, где используется APCI-таймер, винда не самая свежая, либо нет ни invariant TSC, ни HPET. и почему тогда, если НРЕТ не поддерживается чипсетом, то QPF в аккурат равна частоте ACPI-таймера 3.579545 MHz - где параллель с TSC ??? Добавлено Цитата Qraizer @ Сомневаюсь, что кто-то будет использовать QPC для тестов кэша Не исключено, что занижение частоты связано со всякими там Spectre. Ну и да, эта канитель никогда на частоте проца не работала, насколько я понимаю. |