2014-11-26 3 views
1

У меня есть кусок встраиваемых сборок, я компилировать с лязгом ++:RDTSC медленно в Ubuntu

asm volatile ("LFENCE\n\t" 
       "RDTSC\n\t" 
       "shl $32, %%rdx\n\t" 
       "or %%rdx, %%rax\n\t" 
       : "=a" (retval) 
       :: "%rax", "%rdx"); 

На OSX, общая стоимость проверки rdtsc как указано выше, составляет около 10-20 циклов. Когда я компилирую тот же код в Linux (а не виртуальную машину), он занимает около 2500 циклов. Это заставляет меня подозревать, что Linux делает что-то немым, как отключение RDTSC в пространстве пользователя. Из этих статей, это выглядит, по крайней мере были рассмотрены для Linux:

Я бегу Ubuntu 14.04

Вопросы:

  • Был ли режим ядра только rdtsc действительно превратить его в th e Ядро Ubuntu?
  • Если он есть, как определить текущую настройку?
  • И как я могу получить пользовательский режим rdtsc снова?

PS: Я полностью осведомлен о проблеме с rdtsc о неправильных измерениях, промывке трубопровода и т. Д. Я могу жить с ними, и я принимаю меры предосторожности там, где это необходимо. Я просто хочу, чтобы rdtsc был быстрым.

ответ

3

Intel заявила: «Безопасная операционная система установила флаг TSD во время инициализации системы, чтобы отключить доступ пользователя к счетчику отметки времени« с момента его появления 20 лет назад. Большинство ОС игнорировали Intel; и каждые 5 лет или около того какой-то исследователь по безопасности где-то «обнаруживает» новый способ использования такого точного времени для ослабления паролей, ключей шифрования и т. д. Примеры: http://people.csail.mit.edu/tromer/papers/cache.pdf, http://www.daemonology.net/papers/htt.pdf

Если вы добавите к этому проблемы, это тикает с постоянной скоростью (это не на старых процессорах); то проблемы, вызванные тем, что люди принимают его, имеют какое-либо отношение к производительности (это не относится к более новым процессорам); то люди, которые просто используют его неправильно (например, синхронизация одной короткой последовательности, где ошибка является массивной); это начинает казаться еще более худшей идеей.

Если вы добавите к этому проблемы с «out-of_sync TSC» в многопроцессорных системах (особенно в системах NUMA); он становится намного хуже (особенно для ядра, пытающегося сохранить его «вроде синхронизированного»).

Наконец, если вы посмотрите на такие вещи, как счетчики контроля производительности, профайлеры и т. Д .; вы понимаете, что RDTSC является неправильным инструментом для этой работы. Затем вы смотрите в другом направлении в функции «время суток» и «прошедшее время», и понимаете, что там есть достойные/переносные альтернативы.

Примечание: Я не знаю, отключил ли Ubuntu RDTSC в пространстве пользователя на всех системах или только на некоторых системах (например, в тех системах, где он не является постоянной скоростью и/или не синхронизирован между CPU), или даже если они вообще не отключили его. Все, что я знаю, это то, что он должен был быть отключен 20 лет назад.

EDIT: выше ответ на заданный вопрос. Ниже приведен ответ, который вам нужен.

Использовать RDTSC правильно; начните с момента «ничего» в цикле, отбрасывая результаты «выше, чем обычно» (вызванные прерываниями, переключателями задач и т. д.). Используйте это, чтобы найти среднее значение для «ничего» (средние издержки только для RDTSC).

Далее выполните то же самое для кода, который вы тестируете (включая отбрасывание результатов «выше обычного»), чтобы найти средние накладные расходы «RDTSC + ваш код».

И наконец; вычитайте средние издержки только RDTSC из результата «RDTSC + ваш код», чтобы узнать, сколько времени ваш код будет сделан сам по себе.

+1

AL1 это полная и полная битла! ... rdtsc, в аффинитированной нити, которая не переключается на контекст с правильными барьерами на месте, позволяет вам измерять циклы, необходимые для чего-то. И это позволяет делать это ПОКАЗАТЬ, когда вы запускаете код, чтобы вы могли отслеживать его во время выполнения (не только в некоторых тестах). Но лучше всего, вы можете сделать это в фактическом производственном коде (который имеет вышеуказанные свойства) с почти нулевыми накладными расходами (отлично работает в Windows и OSX). Я знаю, что это не тикает с постоянной скоростью - меня это не волнует. –

+1

@ThomasKejser: для этого всегда есть более переносные и безопасные обертки, такие как 'clockgettime()' на Linux и 'QueryPerformanceCounter()' в Windows. В тех случаях, когда RDTSC является нормальным, они часто используют RDTSC (например, без системного вызова или чего-то еще), и когда RDTSC не является нормальным, они не работают. – Brendan

+0

clockgettime() - это сотни ns, rdstc - 20 циклов. Кроме того, clockgettime не дает мне циклов (что я хочу), это дает мне ns (что не полезно для этого случая) .... Есть ли способ настроить Ubuntu просто дать мне доступ к rdtsc в пользовательском режиме? –