Pull to refresh

Comments 24

Думаю, на основе класса Timing и семафора можно решить данную проблему.
Правда, есть одно НО:
Для каждого метода, работающего параллельно придется вызывать методы данного класса, поэтому это не самое хорошее решение…
Конечно, не совсем с помощью семафора (это более мощный механизм), но с помощью счетчика одновременно запущенных потоков в данный момент.
М… RDTSC? Насколько я понимаю, он полностью независим и не привязан к QPC(). Но, конечно, не дает возможности разделить на пользовательское и системное время
Блин, отправилось рано.
В RDTSC есть одна проблема — технологии смены рабочей частоты (IntelSpeedStep) будут влиять на показания счетчика, так что измерения надо будет проводить на постоянной стабилизированной частоте.

В случае, если это неприемлемо, Intel рекомендует использовать т.н. Enhanced timers. Как мне известно, они имеют крайне небольшую погрешность (несколько десятков циклов), но стабилизированны вне зависимости от рабочей частоты процессора
Чтобы не зависить от плавания частоты, все замеры нужно производить в режиме steady state, это когда загрузка CPUs близка к 100%. Данные полученные не в steady state чаще всего недостоверны. Если количество потоков меньше чем количество физических процессоров (ядро также считаем физическим процессором), то нужно устанавливать AffinityMask. У AMD есть хорошая статья на тему Performance Measurements: developer.amd.com/documentation/articles/Pages/1212200690.aspx. Практически все описанное в ней применимо к процессорам Intel.
Почитайте в той же англовики о Constant TSC (Pentium 4 и старше)

en.wikipedia.org/wiki/Time_Stamp_Counter

«Constant TSC behavior ensures that the duration of each clock tick is uniform and supports the use of the TSC as a wall clock timer even if the processor core changes frequency. This is the architectural behavior moving forward for all Intel processors.»

" Since the family 10h (Barcelona/Phenom) AMD chips feature a constant TSC, which can be driven either by the Hypertransport speed or the highest P state. A CPUID bit (Fn8000_0007:EDX_8) advertises this."

Более того, я проверял на синхронность в многоядерных системах. До тех, где добрался — они тикают синхронно (+- сотня тактов)
В википедии, говорите, написано? Счас поправлю.
По той ссылке с сайта Intel написано как раз про то, что SpeedStep меняет частоту и TSC. У меня нет оснований им не верить
Вы еще в ядре линукса поправьте, если вас не затруднит. А то ведь многие используют и не знают.

lxr.linux.no/#linux+v2.6.32/arch/x86/include/asm/cpufeature.h#L79
#define X86_FEATURE_CONSTANT_TSC (3*32+ 8) /* TSC ticks at a constant rate */

lxr.linux.no/#linux+v2.6.32/arch/x86/kernel/cpu/intel.c#L46
46 if ((c->x86 == 0xf && c->x86_model >= 0x03) ||
47 (c->x86 == 0x6 && c->x86_model >= 0x0e))
48 set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC);

64 * c->x86_power is 8000_0007 edx. Bit 8 is TSC runs at constant rate
65 * with P/T states and does not stop in deep C-states.

lxr.linux.no/#linux+v2.6.32/arch/x86/kernel/cpu/amd.c#L414
414 * c->x86_power is 8000_0007 edx. Bit 8 is TSC runs at constant rate
415 * with P/T states and does not stop in deep C-states
Вот эти ваши исходники находятся в противоречии со статьей, что вы дали выше. Там говорится, что TSC = const если степпинг > 0x0F30, в исходниках — если > 0x0F03.

Далее, лично мне из исходников видно, что CONSTANT_TSC включается для степпинга, большего чем 0x0F:0x03 или 0x06:0x0E. Что делать для меньших степпингов при наличии HT/Multicore — ваш комментарий умалчивает
У меня сейчас нет возможности искать подробности в документации от интела.

Для меньшего степпинга (более старых моделей) — не использовать tsc как монотонный источник времени, если включен SpeedStep.

Про HT/multicore — я сам проводил эксперимент (на небольшом количестве машин).
Точных определений не находил, но вот, опять же из ядра линукс

lxr.linux.no/#linux+v2.6.32/arch/x86/kernel/tsc.c#L816
817 * Make an educated guess if the TSC is trustworthy and synchronized
818 * over all CPUs.

833 * Intel systems are normally all synchronized.
834 * Exceptions must mark TSC as unstable:
>>Для меньшего степпинга (более старых моделей) — не использовать tsc как монотонный >>источник времени, если включен SpeedStep.

О, так кто же спорит. Собственно, об этом и речь, как использовать счетчик вне зависимости от режима. Сайт Intel для windows и предлагает либу enhanced timers.
Эта либа 2005 года. Для более новых моделей она, возможно, не так необходима.

Википедия может и не заслуживает доверия во всем, но в данной статье есть отсылка на доки от интела:
Intel 64 and IA-32 Architectures Software Developer's Manual [4], Volume 3A, Chapter 16

www.intel.com/Assets/PDF/manual/253668.pdf

16.11 — про constant, почти то же что и в вики

16.11.1
On processors with invariant TSC support, the OS may use the TSC for wall clock timer services (instead of ACPI or HPET timers).

(8 ядер, рабочая машина)
$ time ./myapp
real 0m1.075s
user 0m7.348s
sys 0m0.071s

Шутка, конечно, но такого хватает в 90% случаев.
Да, но иногда в программе хочется выводить, что эта часть работала столько, а вот эта столько.
UFO just landed and posted this here
real — реальное время. При правильном распараллеливании это время будет в несколько раз(< N_of_cores) меньше суммы user+sys.
user — время, затраченное всеми ядрами в сумме в юзерспейсе(основной код программы)
sys — время, затраченное всеми ядрами в сумме в режиме ядра(системные вызовы: read, write сокетов, time для времени, brk для выделения памяти и т.п.).

Вставьте команду time перед любой другой командой и будете получать такую статистику. Начните с make какого-нить проекта, поиграйтесь.
UFO just landed and posted this here
Пожелание. Указывайте пожалуйста ближе к началу что используется WIndows API или posix.
У меня бывали случаи когда отделение времени в ядре только ухудшало результат (хотя никакого ядерного кода я не писал).
Например, если у нас проблемы с локальностью то лучше просто замерить прошедшее время, потому что мы хотим знать и про килотакты, съеденные свопом.
Обновленный вариант статьи "Вечный вопрос измерения времени".

Тем кому интересна данная тематика, также рекомендую заглянуть по этим ссылкам:
Учимся правильно бенчмаркать (в том числе итераторы)
Учимся правильно бенчмаркать 2: как компилятор бьет в спину
Собственно они и подвигли меня на модификацию статьи.
Sign up to leave a comment.