#c #assembly #x86 #cpu #simulation
#c #сборка #x86 #процессор #Симуляция
Вопрос:
Я заинтересован в запуске программы на определенной частоте (например, 25 МГц) на моем процессоре 2 ГГц . Единственный метод, который я могу придумать для выполнения чего-то подобного, — это использование функции ожидания с точностью до микросекунды, но я не уверен в том, как вычислить, как долго поток должен находиться в режиме ожидания, чтобы соответствовать определенной частоте. Есть какие-нибудь советы или другие идеи? Я делаю это на C в ОС Linux X86.
Комментарии:
1. Какова ваша цель / «вариант использования» для этого? Вы пытаетесь измерить производительность на более низких скоростях?
2. Я создал виртуальный процессор и хочу запускать его на определенной частоте.
Ответ №1:
Здесь есть пара проблем. Это первое, что вы пытаетесь имитировать. Современные процессоры синхронизируются с частотой 2 ГГц, но конвейерные инструкции, поэтому для выполнения отдельной инструкции может потребоваться 10-30 тактов. Переводя поток в режим ожидания, вы прерываете конвейерную линию. Второй вопрос заключается в том, насколько детализированным вы хотите сделать свое моделирование. Вам нужно иметь синхронизацию на уровне команд, можем ли мы подделать это, поместив некоторый пробел между функциями.
Моя последняя мысль заключается в том, что вы, вероятно, хотите имитировать не современный процессор, работающий на частоте 25 МГц, а какой-нибудь тип чипа ARM на встроенном устройстве. Если это так, то на рынке уже есть очень хорошие симуляторы для большинства этих чипов. Скомпилируйте свой код в соответствии с собственными инструкциями для вашего целевого чипа, они используют уже доступный симулятор, если он доступен.
Редактировать:
Итак, как я теперь понимаю, вы хотите выполнить инструкцию на виртуальном процессоре 25 миллионов раз в секунду. Что я мог бы попробовать, так это адаптивный подход. У вас есть много времени, чтобы «возиться» с инструкциями. начните с установки некоторого интервала, вероятно, сработает режим ожидания, между каждой инструкцией. Обратите внимание, что в массиве с максимально возможной точностью, когда запускаются каждые виртуальные часы, сохраняйте скользящее среднее значение, скажем, за последние 25, 100 или 1000 циклов. Если среднее значение поднимается выше 25 МГц, начните добавлять больше места. Если это слишком медленно, уменьшите пространство.
Как я уже говорил изначально, очень сложно рассчитать количество времени, которое команда занимает на современном процессоре. Первый набор команд может выполняться немного слишком быстро или медленно, но подобный метод должен поддерживать его скорость, максимально близкую к нужной, как у обычного генератора в сопоставимой аппаратной реализации.
Комментарии:
1. Такой ответ не помогает. Автор спросил, как, а не где приобрести уже существующее программное обеспечение.
2. Subwar, когда я писал этот ответ, комментарий «Я создал виртуальный процессор …» не был опубликован. Я ответил на вопрос, который, как мне казалось, был задан, который заключался в том, как имитировать запуск процессора X86 с частотой 2 ГГц на частоте 25 МГц. Во втором абзаце было предположение, что это не совсем то, что он хотел сделать. Оказывается, я был наполовину прав. Он действительно хотел имитировать другой процессор, просто не существующий ранее.
3. Я поторопился. Извиняюсь, друг 🙂
Ответ №2:
Я бы предложил архитектуру, управляемую событиями: на каждом ШАГЕ (1 / Гц) запускайте 1 операцию инструкции.
Ответ №3:
Я бы просто запускал симуляцию пакетами. Например, вы могли бы запустить 250 тысяч циклов, затем перейти в режим ожидания на оставшуюся часть интервала в 10 мс. Вы могли бы настроить вид часов, который видит симуляция, чтобы сделать это полностью прозрачным, если только это не связано с каким-либо внешним оборудованием, с которым необходимо взаимодействовать с определенной скоростью (в этом случае это становится гораздо более сложной проблемой).
Ответ №4:
Подводя итог сказанному в приведенных выше ответах, если вы в пользовательском режиме пытаетесь эмулировать виртуальный процессор на определенной частоте, вам следует реализовать какое-то ручное «планирование» потока, который обрабатывает инструкции процессора либо с помощью вызовов режима ожидания, либо с помощью более продвинутых функций и возможностей, таких как fibers в Windows. Предостережение, на которое вам следует обратить внимание, заключается в том, что некоторые вызовы режима ожидания ОС не переходят в режим ожидания в течение точно указанного вами промежутка времени, поэтому вам, возможно, придется добавить дополнительный код для калибровки отклонения от компьютера к компьютеру, чтобы приблизиться к целевой частоте. Чаще всего вы не сможете точно запланировать работу вашего виртуального процессора на постоянной частоте 25 МГц (более вероятно, что 22-28 МГц). В любом случае, я согласен как с Натаном, так и с идеей burst. Удачи, какой бы путь вы ни использовали!
Комментарии:
1. Чтобы вычислить количество секунд, вы должны использовать некоторую сборку для определения времени выполнения некоторого фиктивного кода (кода, который, скорее всего, будет выполнен). Затем выведите какой-нибудь алгоритм (путем экспериментов), связывающий время, необходимое для выполнения кода, с размером выполняемого фиктивного кода. Вы можете использовать этот алгоритм для дальнейшего вычисления того, сколько времени потребуется для запуска кода вашего виртуального процессора, или, что еще лучше, повторно использовать алгоритм динамически в вашем цикле эмуляции, чтобы определить, как долго он будет находиться в режиме ожидания (учитывайте калибровку).
Ответ №5:
Для виртуальной машины все является виртуальным, включая время. Например, за 123 реальные секунды вы могли бы эмулировать 5432 виртуальные секунды обработки. Распространенный способ измерения виртуального времени — увеличивать (или добавлять что-то к) счетчик «количества циклов» каждый раз, когда эмулируется виртуальная команда.
Время от времени вы пытались бы синхронизировать виртуальное время с реальным. Если виртуальное время слишком сильно опережает реальное, вы вставляете задержку, чтобы позволить реальному времени наверстать упущенное. Если виртуальное время отстает от реального, то вам нужно найти какое-то оправдание замедлению. В зависимости от эмулируемой архитектуры вы можете ничего не поделать; но для некоторых архитектур есть функции управления питанием, такие как регулирование температуры (например, возможно, вы можете притвориться, что виртуальный процессор нагрелся и работает медленнее, чтобы остыть).
Вы также, вероятно, хотите иметь очередь событий, где разные эмулируемые устройства могут сообщать «в определенное время произойдет какое-то событие»; так что, если эмулируемый процессор простаивает (ожидая возникновения события), вы можете перейти к тому, когда произойдет следующее событие. Это обеспечивает естественный способ для виртуальной машины наверстать упущенное, если она работает медленно.
Следующий шаг — определить места, где важна синхронизация, и синхронизировать виртуальное время с реальным только в этих конкретных местах. Если эмулируемая машина выполняет интенсивную обработку и не делает ничего, что видно внешнему наблюдателю, то у внешнего наблюдателя нет способа определить, близко ли виртуальное время к реальному времени или нет. Когда виртуальная машина делает что-то, что видно внешнему наблюдателю (например, отправляет сетевой пакет, обновляет видео / экран, издает звук и т.д.), Вы сначала синхронизируете виртуальное время с реальным временем.
Следующим шагом является использование буферизации для отделения событий, происходящих внутри эмулятора, от того, когда они видны внешнему наблюдателю. Для (утрированного) примера представьте, что эмулируемая машина думает, что сейчас 8: 23 утра, и хочет отправить сетевой пакет, но на самом деле только 8:00 утра. Простое решение — отложить эмуляцию на 23 минуты, а затем отправить пакет. Звучит неплохо, но если (после того, как виртуальная машина отправит пакет) эмулятор изо всех сил старается не отставать от реального времени (из-за других процессов, запущенных на реальном компьютере, или по любой другой причине), эмулятор может отстать, и у вас могут возникнуть проблемы с поддержанием иллюзии, что виртуальное время совпадает с реальным. В качестве альтернативы вы могли бы притвориться, что пакет был отправлен, и поместить пакет в буфер и продолжить эмулировать другие вещи, а затем отправить пакет позже (когда в реальном мире на самом деле 8: 23 утра). В этом случае, если (после того, как виртуальная машина отправит пакет) эмулятор изо всех сил старается не отставать от реального времени, у вас все еще есть 23 минуты запаса.
Ответ №6:
Смотрите подход к этому в эмуляторе CPU Fracas. Авторы представили это на семинаре Heteropar, часть EUROPAR 2010. Они существенно модифицируют планировщик ОС, чтобы разрешить использование пользовательских программ только долей реальной частоты процессора.