2013-11-25 2 views
0

Мы пытаемся включить в драйвер устройства драйвер для нашего оборудования. Процедура бенчмаркинг выглядитПринудительное выполнение команды __rdtsc() в тесте

for(int i = 0; i < lots; i++){ 
    tscStart = __rdtsc(); 
    WRITE_REGISTER_ULONG(ourRegister, ourValue) 
    tscEnd = __rdtsc(); 

    duration = tscEnd - tscStart; 
    // Store duration for later evaluation 
} 

Теперь мы, кажется, есть проблема с процессором переупорядочивания звонки, так что примерно 50% всех случаев, duration является слишком коротким (мы присоединили осциллографом, так мы уверены здесь).

Дополнительные факты (я не знаю, если это уместно, это наш первый раз с такими драйверами):

  • __rdtscp имеет такое же поведение (на машинах, которые поддерживают его)
  • Мы «Пробовал каждую линию с _mm_mfence и/или __cpuid для принудительной сериализации команд
  • Эквивалентный эталон с использованием dummy = READ_REGISTER_ULONG(ourRegister) работает по назначению.
  • Наше аппаратное обеспечение подключается через PCIe

Есть ли способ, чтобы получить машину, чтобы действительно ждать записи, чтобы вернуться, прежде чем принимать во второй раз?

+0

Странные вещи, посмотрели ли вы на сборку, чтобы убедиться, что компилятор не выполняет переупорядочение? Оба '__cpuid' и' __rdtscp' должны гарантировать, что ЦП сериализуется. – Damon

+0

Я должен это сделать, я думаю. Благодаря! Подготовьтесь к следующему вопросу о том, как найти разборку для этого конкретного метода в драйвере режима ядра (где я не могу просто прорваться в него) =) – Jens

+0

Я так и думал, как я мог предотвратить компилятор? (Использование компилятора Visual Studio) – Jens

ответ

1

Как упоминалось в комментариях Хансом Пассантом и Деймоном, попытка использовать __cpuid для сериализации вызовов __rdtsc должна работать, но поскольку процессор не дожидается завершения переноса PCIe, мои данные синхронизации отключены.

Смежные вопросы