Почему CPUID + RDTSC ненадежны?

Я пытаюсь профилировать код для времени выполнения на процессоре x86-64. Я имею в виду этот технический документ Intel, а также просмотрены другие потоки SO, в которых обсуждается тема использования RDTSCP и CPUID+RDTSC здесь и здесь.

В упомянутом выше техническом документе метод с использованием CPUID+RDTSC назван ненадежным, а также подтвержден статистикой.

В чем может быть причина ненадежности CPUID+RDTSC?

Кроме того, графики на рис. 1 (график поведения минимального значения) и рис. 2 (график поведения дисперсии) в том же техническом документе имеют паттерн «прямоугольная волна». Чем объясняется такая закономерность?


person talekeDskobeDa    schedule 24.12.2018    source источник


Ответы (2)


Я думаю, они обнаруживают, что CPUID внутри интервала измерения вызывает дополнительную изменчивость общего времени. Предлагаемое ими исправление в разделе 3.2 Улучшения с использованием инструкции RDTSCP подчеркивает тот факт, что внутри временного интервала отсутствует CPUID, когда они используют CPUID/RDTSC для запуска и RDTSCP/CPUID для остановки.

Возможно, они могли бы обеспечить EAX=0 или EAX=1 перед выполнением CPUID, чтобы выбрать лист данных CPUID для чтения (http://www.sandpile.org/x86/cpuid.htm#level_0000_0000h), если время CPUID зависит от того, какой запрос вы делаете. Кроме этого, я не уверен, почему это может быть.

Или, лучше, используйте lfence вместо cpuid для сериализации OoO exec, не являясь полной операцией сериализации.


Обратите внимание, что встроенный ассемблер в технической документации Intel отстой: нет необходимости в этих инструкциях mov, если вы используете правильные ограничения вывода, такие как "=a"(low), "=d"(high). См. Как получить количество циклов ЦП в x86_64 из C++? для более эффективных способов.

person Peter Cordes    schedule 24.12.2018
comment
Дополнительный CPUID, вмешивающийся в измерение, понятен. Однако вторая часть вашего ответа пока не ясна. - person talekeDskobeDa; 24.12.2018
comment
@Pramod: я предполагаю, что включение CPUID в интервал измерения может быть менее плохим, если вы убедитесь, что EAX = 0 при его запуске (sandpile.org/x86/cpuid.htm#level_0000_0000h), на случай, если некоторые листья запрашиваются дольше, чем другие. - person Peter Cordes; 24.12.2018
comment
Ах хорошо. Спасибо! Что может быть причиной прямоугольной формы волны? Изначально я думал, что это может быть что-то связанное с Cache. Но в разделе 1.2 предполагается, что все факторы недетерминизма удалены. Я считаю, что кэширование также способствует недетерминизму. У вас есть какие-нибудь мысли по этому поводу? - person talekeDskobeDa; 24.12.2018
comment
@Pramod: у меня нет этому объяснения. Мне тоже любопытно. Я просмотрел газету, но не увидел, какой код, по их словам, они измеряют. Возможно, они просто измеряют пустой блок, чтобы оценить накладные расходы, поэтому rdtsc и rdtscp стоят друг за другом? Я не думаю, что внутри временной области есть доступ к памяти (кэшу). Я не пытался повторить эксперимент на своем процессоре Skylake. Я ожидаю, что пользовательское пространство в системе, в основном простаивающей, должно быть достаточно близко к тому, что они делают (в ядре с отключенными прерываниями). - person Peter Cordes; 24.12.2018
comment
да. Ты прав. Они измеряют пустой блок, строка 46 кода в Приложении. Под кешем я имел в виду кеш инструкций. Это хорошая идея, чтобы попробовать это на какой-нибудь платформе (на ПК процессор не так интересен, а также я боюсь изменять код ядра, по крайней мере, пока :)) - person talekeDskobeDa; 24.12.2018

Еще одна причина, по которой CPUID+RDTSC ненадежна, связана с атакой по стороннему каналу виртуальной машины.

Когда выполнение инструкции CPUID внутри виртуальной машины вызывает выход виртуальной машины, это происходит, поэтому виртуальная машина будет обрабатывать CPUID по своему усмотрению и манипулировать инструкцией CPUID.
выполнение этой манипуляции добавляет дополнительное время, а использование RDTSC возвращает «высокое» значение, поскольку за это время выполняется «вся манипуляция CPUID виртуальной машины».
Затем это значение можно использовать для определения того, что мы работаем внутри виртуальной машины.

Этому поведению может препятствовать виртуальная машина, которая может масштабировать или виртуализировать TSC, что делает RDTSC ненадежным.

Обнаружение служебной информации при выходе из ВМ

person Matt. Stroh    schedule 04.01.2019