Одной из основных трудностей является правильное выполнение первого вызова.
Как только вы решите это, выяснив, какая инструкция вызвала ошибку, эмулируя ее и изменяя сохраненное состояние задачи, проблема становится производительностью цикла, содержащего popcnt
, который выполняет 1 миллион итераций после того, как вы оптимистично отправили popcnt
версию этого цикла.
Если бы весь ваш код был написан на ассемблере (или компиляторы могли бы сделать этот код за вас), это может быть правдоподобно, но обработчику сигнала сложно собрать все необходимое состояние и возобновить выполнение в другой версии такого кода. петля.
(Обработчики сигналов GNU/Linux получают нестандартное состояние сохраненного регистра потока, в котором они работают, поэтому теоретически вы можете сделать это там.)
Предположительно, это актуально только для предварительной компиляции; если вы используете JIT, вы должны просто проверить CPUID заранее, а не создавать пути обработки исключений.
Возможность эффективной диспетчеризации означает, что ваш код, вероятно, уже написан с указателями функций для многоверсионных функций.
Таким образом, единственным спасением здесь является одна простая функция инициализации, которую ваша программа запускает один раз, которая запускает CPUID пару раз и устанавливает все указатели функций. Выполнение этого позже лениво по мере необходимости означает больше промахов кэша, если только многие указатели функций не остаются неиспользованными. например large-program --help
.
Код для этих обработчиков исключений/сигналов, вероятно, будет не меньше, чем простые функции инициализации. Интересная идея, но в целом я не вижу никакой значимой пользы.
Вам также необходимо знать, какая инструкция вызвала ошибку, если ваша программа использует несколько функций ЦП.
Если вы эмулируете или что-то в этом роде, вам нужно будет проверить это, чтобы увидеть, не является ли это одной из ваших ожидаемых инструкций, которая может вызвать #UD
execptions / сигналы SIGILL. например путем проверки машинного кода по адресу неисправности.
Но если бы вместо этого у вас были функции, отслеживающие, какую оптимистичную отправку они только что сделали (чтобы они могли определить, не сработала ли она), вам нужно было бы устанавливать переменную перед каждой отправкой, так что на самом деле это дополнительные накладные расходы.
person
Peter Cordes
schedule
26.04.2020