Rdtsc

Материал из Википедии — свободной энциклопедии
Перейти к: навигация, поиск

rdtsc (англ. Read Time Stamp Counter) — ассемблерная инструкция для платформы x86, читающая счётчик TSC (Time Stamp Counter) и возвращающая его в регистрах EDX:EAX 64-битное количество тактов с момента последнего сброса процессора.

rdtsc поддерживается в процессорах Pentium (и совместимых с ними) и более новых. Опкод: 0F 31.

rdtscp поддерживается начиная с Intel Nehalem и AMD Family 0x0F[1]. Опкод: 0F 01 F9.[2]

Содержание

[править] Использование

rdtsc чаще всего используется:

  • для измерения времени;
  • для точного измерения временных интервалов;
  • при оптимизации — для измерения времени, необходимого для выполнения конкретных инструкций или их набора;
  • в антиотладочных целях;[3][4]
  • как источник энтропии для генераторов псевдослучайных чисел.[5]

[править] Преимущества

В сравнении с предоставляемыми операционными системами API (при условии отсутствия перечисленных ниже проблемами) вроде WINAPI::QueryPerformanceCounter() или gettimeofday() инструкция rdtsc предоставляет следующие преимущества.

  • Точность почти до тика, что особенно критично для архитектур и операционных систем, не поддерживающих (полноценно) HPET, то есть всех сколько-то устаревших ПК и ОС (для win32 начиная только с Windows Vista, требуется включение опции BIOS «HPET Support»), где используется системный таймер (его точность не чаще OsTimeSlice — 10-15ms). Для win32.2k+ см.напр. параметр /usepmtimer в boot.ini в статье о NTLDR)</ref>
  • Скорость, обычно в десятки-сотни тысяч раз быстрее (в зависимости от множества факторов). Это очень важно, например, при измерении времени исполнения интенсивных операций, таких, как вызовы функций.
  • Не требует переключения в Ring0 в большинстве систем (если команда разрешена в данной ОС).
  • QueryPerformanceCounter может работать неправильно в Windows Server 2000, Windows Server 2003 и Windows XP.[6]

[править] Проблемы использования

  • При создании коммерческих программ RDTSC потенциально может быть недоступна на конечной системе, поэтому должны быть предусмотрены режимы функционирования, не требующие данной команды.
  • Точные замеры:
    • невозможность получения точного значения из-за влияния кэшей процессора при обращении к памяти, да и просто исполнение команд требует предвыборки оттуда же. Традиционно решается многократным измерением фрагмента программы.
    • возможность переупорядочивания с замеряемыми командами на Out-of-Order процессорах. Решается добавлением сериализующих команд (например, CLD/CLC для Pentium моделей P5, P54[7] или cpuid для более новых) или использованием rdtscp.
  • возможная недоступность:
    • на старых процессорах (например, 80486) либо на процессорах, реализующих архитектуру x86 не в полном объеме.
    • инструкция может быть потенциально превращена в привилегированную (операционной системой установлен 3-й бит в управляющем регистре CR4), и её использование приведет к генерации исключения в программе.
  • режим энергосбережения:
    • В современных процессорах Intel счетчик TSC не зависит от использования технологий энергосбережения и увеличивается на 1 каждый такт, вне зависимости от того, работал ли процессор или находился в состоянии сна.
    • Существует также вопрос периодического динамического автоснижения и автоповышения частот технологиями Cool&Quiet и аналогов от других производителей процессоров, а также технологий псевдоразгона — Intel® Turbo Boost Technology. Для не сильно критических к таймингам систем это обычно обходится периодическим пересчётом частоты, например, в играх (особенно в однопользовательском режиме) и подобных 3D-эмуляторах, а также в реалтайм-счётчиках времени исполнения тех или иных блоков программы.
  • псевдовсплески в системах с многопоточным ядром (ядрами) или HyperThreading для случаев очень точных замеров блока команд из-за неучёта загруженности общих процессорных блоков а также кэша и памяти, что верно и для просто мультипроцессорных систем. Простейшее решение — отключить на время тестов HyperThreading в BIOS, при наличии более одного ядра — в BIOS или программно в ОС ограничить число ядер до одного (для win32 — параметр /numproc=1 в c:\boot.ini).
  • рассинхронизация в многоядерных системах:
    • При инициализации процессоров. В некоторых реализациях счетчики TSC могут иметь синхронные значения на многоядерной системе, в том числе временно, что может ввести программиста в заблуждение о таком же поведение и на других системах.
    • Рассинхронизация самих счётчиков в первых многоядерных системах из-за неверно-синхронной инициализации процессоров некоторыми BIOS. Правится обновлением BIOS или обновлением драйвера операционной стстемы и CPU. Существуют программы для проверки на наличие этой ошибки.[8]
    • Порча оперируемого программой значения счётчика в многоядерных системах, когда частота разная или программа не рассчитана на исполнение на многопроцессорной системе, при периодическом автопереключении потока или процесса с одного процессора на другой системой.
    • Основной проблемой для применения инструкции rdtsc на многоядерных системах (особенно критично это в случае, когда она используется для измерения временных интервалов) является то, что значения счетчика команд на разных процессорных ядрах могут быть разными (не синхронизированными).
    • Для того, чтобы на прикладном уровне можно было отследить факт смены ядра на многоядерных системах, введена инструкция rdtscp, которая, работая аналогично rdtsc, возвращает в регистре ecx дополнительно id процессорного ядра.

Для решения многих проблем рекомендуется фиксирование потока на конкретном процессоре (cpu affinity) и отключение технологий автоматического изменения частоты (в целях энергосбережения или повышения производительности).

[править] Примечания

[править] Ссылки

Личные инструменты
Пространства имён

Варианты
Действия
Навигация
Участие
Печать/экспорт
Инструменты
На других языках