RDTSC, замеры производительности.

Тема в разделе "WASM.ASSEMBLER", создана пользователем cppasm, 6 фев 2009.

  1. cppasm

    cppasm New Member

    Публикаций:
    0
    Регистрация:
    18 июл 2006
    Сообщения:
    923
    Привет.
    Предистория.
    Есть один и тот же алгоритм написанный на MMX и на обычных командах.
    Захотелось померять прирост производительности, воспользовался RDTSC.
    Вроди всё как положено, поставил процессу REAL_TIME_PROIRITY_CLASS, потоку поставил THREAD_PROIRITY_TIME_CRITICAL, поставил AffinityMask для потока только на один процессор и вперёд.
    Делаем 1000000 замеров в цикле и потом вычисляем прирост.
    И вот тут начинаются чудеса.
    Сразу скажу что результаты повторяемые, т.е. это не случайные косяки с RDTSC.
    На однопроцессорной машине всё даёт ожидаемые результаты - ~38% прирост.
    А на многопроцессорной (либо двуядерной, либо просто с HyperThreading) получается ерунда.
    По замерам прироста нет совсем.
    Но! Если нагрузить остальные ядра, то результат получается примерно как на однопроцессорной машине.
    Т.е. если для каждого ядра создать поток в котором делать просто jmp $, результаты такие же как и на однопроцессорной машине.
    И это при том, что поток в котором выполняется измеряемый код жёстко привязан к одному ядру, это к примеру в диспетчере задач видно.
    Вопрос в том что это за приколы такие?
    Как нагрузка на одно ядро может влиять на производительность другого?
    Причём влиять по разному - производительность MMX падает незначительно, а производительность обычных команд типа add/sub/imul - значительно?
    Кто что думает по этому поводу?
     
  2. Pavia

    Pavia Well-Known Member

    Публикаций:
    0
    Регистрация:
    17 июн 2003
    Сообщения:
    2.409
    Адрес:
    Fryazino
    cppasm
    Может на компьюторе стоит энерго сберегающий режим?
     
  3. asmfan

    asmfan New Member

    Публикаций:
    0
    Регистрация:
    10 июл 2006
    Сообщения:
    1.004
    Адрес:
    Abaddon
    Ну много факторов влияния возможно. Много различных состояний производительности процессора. ОС может шалить (видел такие KB в которых фиксились другие KB в которых были ошибки с состояниями производительности)
    http://support.microsoft.com/kb/896256
    http://support.microsoft.com/kb/330512
     
  4. cppasm

    cppasm New Member

    Публикаций:
    0
    Регистрация:
    18 июл 2006
    Сообщения:
    923
    Нет, не стоит...
    Да и какая разница?
    Если на ядре выполняется поток с приоритетом реального времени, то оно просто не может в энергосберегающем режиме находиться.
    Что интересно - если запускать программу из-под VTune то и замеры программы, и результаты VTune получаются такими же как при загрузке всех ядер.
     
  5. s0larian

    s0larian New Member

    Публикаций:
    0
    Регистрация:
    15 июл 2004
    Сообщения:
    489
    Адрес:
    Крыжёпполь
    AFAIK HyperThreading не отдлельное ядро, а так, хитро-жёппый out of order execution... На реальном dual core что происходит с выставленой affinity и без?
     
  6. cppasm

    cppasm New Member

    Публикаций:
    0
    Регистрация:
    18 июл 2006
    Сообщения:
    923
    Ну это не out of order execution...
    Там просто нету полноценного ядра, но некоторые исполнительные блоки дублируются.
    На серваке с двумя Intel Xeon Dual Core (т.е. 2 процессора по два ядра) то же самое.
    При нагрузке на все ядра результаты одни, при нагрузке только на ядро на котором выполняется замеряемый код - другие (я склонен считать что неправильные, на одноядерной машине результаты получаются как на многоядерной с полностью загруженными ядрами)...
     
  7. s0larian

    s0larian New Member

    Публикаций:
    0
    Регистрация:
    15 июл 2004
    Сообщения:
    489
    Адрес:
    Крыжёпполь
    cppasm, ну а без affinity и без дополнительных потоков ты попробовал?
     
  8. cppasm

    cppasm New Member

    Публикаций:
    0
    Регистрация:
    18 июл 2006
    Сообщения:
    923
    Без дополнительных потоков пробовал - результат написан выше.
    А без установки affinity mask (без привязки к ядру) пробовать смысла нету.
    ОС тогда гипотетически может мой поток перекидывать между ядрами, а у каждого из них RDTSC считает независимо, т.е. что я в итоге намеряю непонятно.
     
  9. Pavia

    Pavia Well-Known Member

    Публикаций:
    0
    Регистрация:
    17 июн 2003
    Сообщения:
    2.409
    Адрес:
    Fryazino
    cppasm
    Помойму вы противоречите сами себе.
    Еще раз проверьте все и выложите результаты.

    По моим мыслям HyperThreading - должен работать так.
    Если на одном ядре работает твой код на другом jmp $ то тут должны наблюдаться такиеже результаты как и на одно ядерном.
    Без использования второго ядра HyperThreading будет тормазить и система будет работать медленее.
    Если загрузить оба ядра то прирост несколько процентов. Причем я считаю если на одно ядро поместить код с MMX а надругую обычные команды то прирост будет больше.

    А вот на настоящем двух ядерном такого недолжно наблюдаться.
     
  10. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    cppasm
    Вот именно, что "гипотетически". Если алгоритм позволяет, то лучше не накручивать офигенные циклы, а ноборот стремиться уложиться в микросекунды, тогда и вероятность переключения потока будет достаточно мала. А для отбраковки случайных "сбоев" достаточно делать серию из 8-10 проходов и брать только повторяемые результаты

    Pavia
    В принципе тоже может, если код интенсивно работает с памятью (видимо так оно и есть, раз речь об MMX). В этом случае пустой цикл на втором ядре гарантированно не лезет в память, не засоряет общий кэш L2, и не требует доп.проверок когерентности L1
     
  11. s0larian

    s0larian New Member

    Публикаций:
    0
    Регистрация:
    15 июл 2004
    Сообщения:
    489
    Адрес:
    Крыжёпполь
    Ээ, у двух ядер в одной упаковке общий TSC.
     
  12. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    Откуда дровишки ? ;)
    У AMD точно разные и работают на частоте своего ядра, и соотв-но могут разбегаться при изменении частоты. У Intel скорее всего тоже разные, но работают синхронно на фикс.частоте и поэтому не разбегаются (или скажем так - не должны ;)
     
  13. Pavia

    Pavia Well-Known Member

    Публикаций:
    0
    Регистрация:
    17 июн 2003
    Сообщения:
    2.409
    Адрес:
    Fryazino
    leo
    Во время старта ядра запускаются с опазданием. Поэтому значения TSC отличаются.
     
  14. cppasm

    cppasm New Member

    Публикаций:
    0
    Регистрация:
    18 июл 2006
    Сообщения:
    923
    Нет, не противоречу.

    На одноядерной машине прирост 38%.
    На двуядерной мой код запускается только на одном ядре.
    Если остальные ядра не трогать - то прироста нет совсем, т.е. время выполнения с MMX и без примерно одинаково.
    Если же пригрузить остальные ядра, то скорость MMX кода практически не падает, а скорость обычного кода падает сильно - и получаем те же 38% прироста у MMX.
    Я думал может с кешем ерунда какая-то.
    Но у двуядерных процессоров ведь у каждого ядра свой кеш?
    Если кому интересно могу выложить две тестовые программки, погоняете у кого есть двуядерные процессоры.
     
  15. t00x

    t00x New Member

    Публикаций:
    0
    Регистрация:
    15 фев 2007
    Сообщения:
    1.921
    cppasm
    конечно выкладывайте.
     
  16. Pavia

    Pavia Well-Known Member

    Публикаций:
    0
    Регистрация:
    17 июн 2003
    Сообщения:
    2.409
    Адрес:
    Fryazino
    Зависит от системы.
     
  17. max7C4

    max7C4 New Member

    Публикаций:
    0
    Регистрация:
    17 мар 2008
    Сообщения:
    1.203
    а для четырехядерных подойдут?
     
  18. cppasm

    cppasm New Member

    Публикаций:
    0
    Регистрация:
    18 июл 2006
    Сообщения:
    923
    В смысле? От какой системы?
    Да, для любых подойдут, даже для однопроцессорных. :)

    В архиве два файла - speedcmp_st.exe и speedcmp_mt.exe, соответственно однопоточная и многопоточная версия.
    У меня результаты такие.
    Однопоточная:
    Многопоточная:
    Ещё раз подчеркну, что в многопоточной версии замеряемый код всё равно работает в одном потоке, в остальных потоках просто пустой цикл while(loop_thread);

    И всё равно на P4 MMX как-то туго работает.
    Проверял ещё на Celeron D и на AMD Duron - прирост намного выше.
     
  19. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    в обоих ~20%. Тестил раз 10.
    Q6600
    Не пробовал после установки аффинита делать Sleep(0) ?

    Код (Text):
    1. ===============================
    2. Performing ALGO speed test...
    3. ===============================
    4. Execution time (fix)  ->   57217941 clocks
    5. Execution time (mmx)  ->   45160083 clocks
    6.  
    7. 21% speedup.
    8.  
    9. ===============================
    10. Performing ALGO speed test...
    11. ===============================
    12. Execution time (fix)  ->   58734189 clocks
    13. Execution time (mmx)  ->   45895005 clocks
    14.  
    15. 21% speedup.
     
  20. cppasm

    cppasm New Member

    Публикаций:
    0
    Регистрация:
    18 июл 2006
    Сообщения:
    923
    Пробовал, не помогает.

    Погонял тут ещё - похоже HyperThreading такие чудеса творит.
    На AMD Opteron Dual-Core (2 CPU по два ядра) результаты в обоих вариантах идентичны.
    На Intel Xeon (2 CPU одноядерных с HyperThreading) - эффект наблюдается, разброс есть ~15%