Как мне обеспечить, чтобы моя программа работала от начала до конца без перерывов?

StackOverflow https://stackoverflow.com/questions/1215713

  •  06-07-2019
  •  | 
  •  

Вопрос

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

Это было полезно?

Решение

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

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

Другие советы

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

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

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

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

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

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

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

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

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

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

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

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

Пример кода бенчмарка RDTSC

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top