Как я могу гарантировать, что моя программа работает от начала до конца без перерыва?
Я пытаюсь рассчитать время кода с помощью 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]tt%u [%llu]n", i, ans, diff);
else
printf("%llun", diff);
}
}
Дополнительные очки тем, кто заметил, что я не правильно обрабатываю условия переполнения в этом коде. На данном этапе я просто пытаюсь получить последовательный вывод без резких скачков из-за того, что моя программа теряет время.
Хорошее значение ибо моя программа -20.
Итак, чтобы резюмировать, возможно ли для меня запустить этот код без перерыва из операционной системы? Или мне нужно будет запустить его на голом оборудовании в ring0, чтобы я мог отключить IRQ и планирование? Заранее спасибо!
7 ответов:
Если вы вызываете nanosleep() для сна на секунду или около того непосредственно перед каждой итерацией теста, вы должны получить "свежий" timeslice для каждого теста. Если вы компилируете ядро с прерываниями таймера 100 Гц, и ваша функция timed завершается менее чем за 10 мс, то вы должны быть в состоянии избежать прерываний таймера, поражающих вас таким образом.
Чтобы свести к минимуму другие прерывания, деконфигурируйте все сетевые устройства, настройте систему без подкачки и убедитесь, что она в противном случае не работает.
Хитро. Я не думаю, что вы можете отключить операционную систему и гарантировать строгое планирование.
Я бы перевернул это с ног на голову: учитывая, что он работает так быстро, запустите его много раз, чтобы собрать распределение результатов. Учитывая, что стандартная Ubuntu Linux не является ОС реального времени в узком смысле, все альтернативные алгоритмы будут работать в одной и той же установке-и вы можете сравнить свои дистрибутивы (используя что угодно от сводной статистики до квантилей и qqplots). Ты можешь это сделать. сравнение с Python, или R, или Octave,... какой подходит вам лучше всего.
Вам может сойти с рук запуск FreeDOS, так как это один процесс OS.
Вот соответствующий текст из второй ссылки:
Реализация DOS Microsoft, которая является de фактический стандарт для систем DOS в x86 world, является однопользовательским, однозадачная операционная система. Оно обеспечивает необработанный доступ к оборудованию, и только минимальный уровень для API ОС для такие вещи, как файл ввода-вывода это хорошая вещь, когда дело доходит до встроенный системы, потому что вам часто просто нужно чтобы что-то сделать без помощи операционная система на вашем пути.
DOS не имеет (изначально) понятия потоки и отсутствие понятия множественности, текущие процессы. Приложение программное обеспечение делает системные вызовы через использование интерфейса прерывания, вызов различные аппаратные прерывания для обработки такие вещи, как видео и аудио, и вызов программных прерываний для обработки различные вещи, такие как чтение каталог, выполнение файла и так далее.
Конечно, вы, вероятно, получите лучшую производительность, загружая FreeDOS на реальное оборудование, а не в эмулятор.
На самом деле я не использовал FreeDOS, но я предполагаю, что поскольку ваша программа кажется стандартной C, вы сможете использовать любой стандартный компилятор для FreeDOS.
Если ваша программа выполняется в миллисекундах, и если вы работаете на Linux, Убедитесь, что частота таймера (в linux) установлена на 100 Гц (не 1000 Гц). (cd / usr / src / linux; сделайте menuconfig и посмотрите на "тип процессора и функции" - > " частота таймера") Таким образом, ваш процессор будет прерываться каждые 10 мс.
Кроме того, учтите, что срез времени процессора по умолчанию в Linux составляет 100 мс, поэтому при хорошем уровне -20 вы не будете отменены, если вы работаете в течение нескольких часов. миллисекунды.
Кроме того, вы зацикливаетесь 101 раз на fn(). Пожалуйста, рассмотреть вопрос о предоставлении ФН() быть не правильно откалибровал вашу систему.
Сделайте статистику (average + stddev) вместо того, чтобы печатать слишком много раз (что потребило бы ваше запланированное время, и терминал в конечном итоге получит расписание и т. д... избегать этого).
Вы можете использовать chrt-f 99 ./ тест для запуска ./ тест с максимальным приоритетом в реальном времени. Тогда, по крайней мере, он не будет прерван другими процессами пользовательского пространства.
Кроме того, при установке пакета linux-rt будет установлено ядро реального времени, которое даст вам больше контроля над приоритетом обработчика прерываний через потоковые прерывания.