Этот вопрос является дополнительным вопросом на Can the C compiler optimizer violate short-circuiting and reorder memory accesses for operands in a logical-AND expression?.Как спекулятивная ошибка из-за оптимизации компилятора реализована под капотом?
Рассмотрите следующий код.
if (*p && *q) {
/* do something */
}
Теперь согласно дискуссии на Can the C compiler optimizer violate short-circuiting and reorder memory accesses for operands in a logical-AND expression? (особенно Дэвид Шварц комментарий и ответ) можно для оптимизатора стандартных-совместимых C компиляторов испускать инструкции центрального процессора, который обращается к *q
до того *p
при сохранении наблюдаемого поведения точки последовательности, установленной с оператором &&
.
Поэтому, хотя оптимизатор может испускать код, который получает доступ к *q
перед тем *p
, она по-прежнему необходимо обеспечить, чтобы любые побочные эффекты *q
(такие как ошибки сегментации) наблюдается только тогда, когда *p
не равен нулю. Если *p
равно нулю, то ошибка, вызванная *q
, не должна наблюдаться, т. Е. Произойдет спекулятивная ошибка сначала из-за того, что сначала выполняется на CPU *q
, но спекулятивная ошибка будет проигнорирована, как только выполняется *p
и считается 0.
Мой вопрос: как эта спекулятивная ошибка выполняется под капотом?
Я был бы признателен, если бы вы могли наложить больше света на следующие моменты, отвечая на этот вопрос.
- Насколько я знаю, когда процессор обнаруживает ошибку, он генерирует ловушку, что ядро должно обработать (либо принять меры для восстановления, такие как страницы подкачки, или сигнал о неисправности, такие как SIGSEGV процессу) , Я прав?
- Итак, если компилятор должен испускать код для выполнения спекулятивной ошибки, мне кажется, что ядро и компилятор (и, возможно, процессор тоже) должны взаимодействовать друг с другом для реализации спекулятивной ошибки. Как компилятор испускает инструкции, которые указывают ядру или процессору, что ошибка, вызванная кодом, должна считаться спекулятивной?
Если '* q' обращается безоговорочно * до или после' if (* p && * q) ', компилятор может сделать вывод о том, что доступ не может быть вызван ошибкой в соответствующей программе и, следовательно, изменить порядок доступа. – EOF