4

Я ищу способы выполнения микро-тестов на многоядерных процессорах.Как тестировать многоядерные процессоры

Контекст:

примерно в то же время настольных процессоров введенными вне порядка исполнения, который сделал производительность трудно предсказать, что они, возможно, не случайно, также введены специальные инструкции, чтобы получить очень точные тайминги. Пример этих инструкций: rdtsc на x86 и rftb на PowerPC. Эти инструкции давали тайминги, которые были более точными, чем когда-либо позволяли системный вызов, позволяли программистам микроконтролировать их сердца, к лучшему или к худшему.

На еще более современном процессоре с несколькими ядрами, некоторые из которых спят некоторое время, счетчики не синхронизируются между ядрами. Нам говорят, что rdtsc больше не безопасно использовать для бенчмаркинга, но я, должно быть, уже дремал, когда нам объясняли альтернативные решения.

Вопрос:

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

Некоторые системы могут позволить отключить сердечники, оставив только один ход. Я знаю, что Mac OS X Leopard делает, когда правильная панель предпочтений установлена ​​в Инструментах разработчиков. Считаете ли вы, что это сделать rdtsc безопасным для использования снова?

Больше контекст:

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

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

  2. Мне нужны цифры для публикации в публикации, срок которой я не контролирую.

ответ

2

На OSX (ARM, Intel и PowerPC), вы хотите использовать mach_absolute_time():

#include <mach/mach_time.h> 
#include <stdint.h>  

// Utility function for getting timings in nanoseconds. 
double machTimeUnitsToNanoseconds(uint64_t mtu) { 
    static double mtusPerNanosecond = 0.0; 
    if (0.0 == mtusPerNanosecond) { 
     mach_timebase_info_data_t info; 
     if (mach_timebase_info(&info)) { 
      // Handle an error gracefully here, whatever that means to you. 
      // If you do get an error, something is seriously wrong, so 
      // I generally just report it and exit(). 
     } 
     mtusPerNanosecond = (double)info.numer/info.denom; 
    } 
    return mtu * mtusPerNanosecond; 
} 

// In your code: 
uint64_t startTime = mach_absolute_time(); 
// Stuff that you want to time. 
uint64_t endTime = mach_absolute_time(); 
double elapsedNanoseconds = machTimeUnitsToNanoseconds(endTime - startTime); 

Обратите внимание, что нет необходимости ограничивать одно ядро ​​для этого. Операционная система обрабатывает исправление, требуемое за кулисами, для mach_absolute_time(), чтобы дать вялые результаты в многоядерной (и многосоставной) среде.

+0

Спасибо, я должен уметь работать с http://developer.apple.com/mac/library/qa/qa2004/qa1398.html, хотя я очень разочарован результатом 'man mach_absolute_time'. –

+0

@Pascal: Это будет хорошая ошибка для отчета. Я разместил некоторый пример кода, который позволяет избежать кастования указателя в этой заметке. –

+0

Обратите внимание, что это решение будет страдать от эффекта зонда намного больше, чем привязка вашего процесса к одному ядру и дважды используя rtdsc (на x86, не могу говорить для PowerPC). Компилятор может не встраивать ваши функции, они будут занимать больше кэша команд, и вы делаете умножения и деления, которые, как я полагаю, могут варьироваться в зависимости от того, сколько времени они выполняют для завершения на основе их операндов. «rtdsc» просто считывает реестр и, следовательно, намного дешевле и меньше влияет на ваши результаты. –

1

Ядра возвращают правильные синхронизированные значения для «rtdsc». Если у вас есть машина с несколькими дисками, вы должны исправить процесс в один сокет. Это не проблема.

Основная проблема заключается в том, что планировщик делает данные ненадежными. Существует несколько API производительности для ядра Linux> 2.6.31, но я не смотрел на него. Windows> Vista отлично справляется здесь, используйте QueryThreadCycleTime и QueryProcessCycleTime.

Я не уверен насчет OSX, но AFAIK «mach_absolute_time» не корректирует запланированное время.

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