2009-08-01 2 views
2

Я пытаюсь использовать код времени, используя RDTSC (никакое другое программное обеспечение для профилирования, которое я пробовал, не имеет времени на нужное разрешение) на Ubuntu 8.10. Тем не менее, я продолжаю получать выбросы от переключения задач и прерываний, что приводит к тому, что моя статистика недействительна.Как обеспечить, чтобы моя программа выполнялась от начала до конца без перерывов?

Учитывая, что моя программа работает в миллисекундах, можно ли отключить все прерывания (которые по сути отключили переключатели задач) в моей среде? Или мне нужно перейти к ОС, которая позволяет мне больше мощности? Будет ли я лучше использовать свое собственное ядро ​​ОС для выполнения этого кода времени? Я пытаюсь доказать лучшую/худшую производительность алгоритма, поэтому он должен быть полностью прочным с учетом времени.

Соответствующий код, я использую в настоящее время является:

inline uint64_t rdtsc() 
{ 
    uint64_t ret; 
    asm volatile("rdtsc" : "=A" (ret)); 
    return ret; 
} 

void test(int readable_out, uint32_t start, uint32_t end, uint32_t (*fn)(uint32_t, uint32_t)) 
{ 
    int i; 
    for(i = 0; i <= 100; i++) 
    { 
     uint64_t clock1 = rdtsc(); 
     uint32_t ans = fn(start, end); 
     uint64_t clock2 = rdtsc(); 

     uint64_t diff = clock2 - clock1; 

     if(readable_out) 
      printf("[%3d]\t\t%u [%llu]\n", i, ans, diff); 
     else 
      printf("%llu\n", diff); 
    } 
} 

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

Хорошее значение для моей программы - -20.

Итак, для того, чтобы я мог запустить этот код без перерыва из ОС? Или мне нужно будет запустить его на голом оборудовании в ring0, чтобы я мог отключить IRQ и планирование? Заранее спасибо!

+0

Вы пробовали OProfile: http://oprofile.sourceforge.net/news/ –

ответ

3

Если вы звоните nanosleep(), чтобы спать на второй или так непосредственно перед каждой итерации теста, вы должны получить «свежий» квант времени для каждого теста. Если вы скомпилируете ядро ​​с прерываниями таймера 100 Гц и ваша временная функция завершится менее чем за 10 мс, вы должны быть в состоянии избежать прерываний таймера, которые попадают вам так.

Чтобы свести к минимуму другие прерывания, деконфигурируйте все сетевые устройства, настройте свою систему без свопинга и убедитесь, что она в остальном спокойна.

+0

Я пробовал аналогично с sched_yield, что улучшило набор результатов на честный бит. –

2

Tricky. Я не думаю, что вы можете отключить операционную систему и гарантировать строгое планирование.

Я бы повернул это с ног на голову: учитывая, что он работает так быстро, запустите его много раз, чтобы собрать распределение результатов. Учитывая, что стандартный Ubuntu Linux не является операционной системой в режиме реального времени в узком смысле, все альтернативные алгоритмы будут работать в одной и той же настройке --- и затем вы можете сравнить свои дистрибутивы (используя что-либо из сводной статистики для квантилей в qqplots). Вы можете сделать это сравнение с Python, или R, или Octave, ... в зависимости от того, что вам подходит.

+1

Я работаю над этим (отсюда цикл for). Проблема в том, что выбросы значительно больше, чем остальная часть данных, которая сбрасывает мое среднее и стандартное отклонение. –

+0

Но теперь у нас есть статистическое обсуждение :-) Среднее и стандартное отклонение полностью описывают нормальное распределение, но ваши данные могут не распространяться нормально. Попытайтесь описать хвост, особенно «плохой», с квантилями и сюжетами, если сможете. Это худший случай, который вы сравниваете с альтернативами ... что может быть хуже. [Конечно, остальная часть дистрибутива нуждается в описательных документах ...] –

+0

Действительный пункт. Однако это разочаровывает, если иметь более 90 ценностей около 11 000 - 12 000, а затем иметь некоторую ценность, достигая 50 000, и сбросить все это. Это просто лишние значения, которые так ошибаются *, что они значительно влияют на статистику, которую я пытаюсь создать. –

0

Если вы используете root, вы можете вызвать sched_setscheduler() и дать себе приоритет в реальном времени. Проверьте документацию.

2

Возможно, вам будет нужно сбежать с FreeDOS, так как it's a single process OS.

Вот соответствующий текст из второй ссылки:

реализация DOS Microsoft, которая является де факто стандартом для систем DOS в x86 мире, является однопользовательской, однозадачными операционной система. Он обеспечивает необработанный доступ к оборудованию, а - только минимальный уровень для API OS для таких вещей, как файл ввода-вывода. Это хорошая вещь, когда дело доходит до встроенных систем , потому что вам часто просто нужно , чтобы что-то сделать без операционной системы .

DOS имеет (изначально) концепцию потоков и концепций нескольких, текущих процессов.Применение программного обеспечение делает системные вызовы через использования прерывания интерфейса, вызывая различных аппаратные прерывания для обработки вещи, как видео и аудио, и вызова программного прерывания для обработки различных вещей, как чтение каталога , выполнение файла и так вперед.

Конечно, вы, вероятно, получите наилучшую производительность, фактически загрузив FreeDOS на фактическое оборудование, а не в эмулятор.

У меня на самом деле нет FreeDOS, но я предполагаю, что, поскольку ваша программа, кажется, стандартная C, вы сможете использовать любой стандартный компилятор для FreeDOS.

+0

Хорошая ссылка - хороший ol 'DOS бросает компьютер в запущенные программы, что очень хорошо работает для такого рода вещей. –

1

Вы можете использовать chrt -f 99 ./test для запуска ./test с максимальным приоритетом в реальном времени. По крайней мере, это не будет прервано другими процессами пространства пользователя.

Кроме того, установка пакета linux-rt будет устанавливать ядро ​​реального времени, что даст вам больше контроля над приоритетом обработчика прерываний с помощью поточных прерываний.

+0

Кроме того, с помощью патчей linux RT (http://rt.wiki.kernel.org/index.php/Main_Page) латентность от прерываний будет минимизирована – bdonlan

2

Если ваша программа работает в миллисекундах, а если вы работаете в Linux, Убедитесь, что ваша частота таймера (в Linux) установлена ​​на 100 Гц (не 1000 Гц). (cd/usr/src/linux; make menuconfig и посмотрите «Тип процессора и функции» -> «Частота таймера») Таким образом ваш процессор будет прерван каждые 10 мс.

Кроме того, считайте, что срез процессорного времени по умолчанию для Linux равен 100 мс, поэтому с хорошим уровнем -20 вы не будете отправлены, если вы работаете в течение нескольких миллисекунд.

Кроме того, вы накладываете 101 раз на fn(). Пожалуйста, подумайте о том, чтобы дать fn() быть no-op для правильной калибровки вашей системы.

Сделать статистику (в среднем + stddev) вместо печати слишком много раз (что будет потреблять запланированный тайм-лист, а терминал в конечном итоге получит расписание и т. Д.), Избегайте этого).

RDTSC benchmark sample code

+0

Спасибо за советы. –

0

Возможно, есть какой-то способ отключить превентивное планирование в Linux, но может быть и не нужно. Вы могли бы использовать информацию от /proc/<pid>/schedstat или какого-либо другого объекта в /proc, чтобы понять, когда вы были выгружены, и не обращайте внимания на эти временные выборки.