Как мне убедиться, что моя программа работает от начала до конца без перерыва? - PullRequest
2 голосов
/ 01 августа 2009

Я пытаюсь рассчитать время с помощью 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 и планирование? Заранее спасибо!

Ответы [ 7 ]

3 голосов
/ 01 августа 2009

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

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

2 голосов
/ 01 августа 2009

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

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

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

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

Код образца эталонного теста RDTSC

2 голосов
/ 01 августа 2009

Возможно, вам удастся запустить FreeDOS , поскольку это ОС с одним процессом .

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

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

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

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

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

2 голосов
/ 01 августа 2009

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

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

1 голос
/ 01 августа 2009

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

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

0 голосов
/ 01 августа 2009

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

0 голосов
/ 01 августа 2009

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

...