Каков фактический эффект успешных безусловных доступов на x86?

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

Предположим, что я нахожусь на x86 и имею некоторую (пока неизвестную) долю неприглашенных доступов - каково наихудшее замедление на самом деле и как я могу оценить его, не исключая всех неприглашенных доступов и сравнивая время выполнения двух версий кода?

Ответы

Ответ 1

Это зависит от инструкции (ов), для большинства инструкций по загрузке/хранению x86 SSE (за исключением невыложенных вариантов), это вызовет ошибку, что означает, что это, вероятно, приведет к краху вашей программы или приведет к большому количеству поездок в оба конца обработчик исключений (что означает, что почти или вся производительность теряется). Неравнозначные варианты загрузки/хранения выполняются с удвоенным количеством циклов IIRC, поскольку они выполняют частичное чтение/запись, поэтому 2 требуется для выполнения операции (если только вам не повезло и ее кэш, что значительно снижает штраф).

Для общих инструкций по загрузке/хранению x86 штраф равен скорости, так как требуется больше циклов для чтения или записи. unalignment также может повлиять на кэширование, что приводит к расщеплению строки кэша, и кэш-границам. Это также предотвращает атомарность при чтении и записи (которые гарантированы для всех выровненных чтения/записи x86, барьеры и распространение - это что-то еще, но использование команды LOCK'а на неуравновешенных данных может вызвать и исключить или значительно увеличить и без того массивное наказание bu lock incurs), который является no-no для параллельного программирования.

Руководство по оптимизации Intels x86 и x64 подробно описывает каждую вышеупомянутую проблему, их побочные эффекты и способы их устранения.

Руководства по оптимизации Agner Fog должны иметь точные числа, которые вы ищете с точки зрения пропускной способности сырого цикла.

Ответ 2

На некоторых микроархитектурах Intel нагрузка, разделенная границей кешлин, занимает дюжину циклов дольше, чем обычно, а нагрузка, разделенная границей страницы, занимает более 200 циклов. Достаточно плохо, что если нагрузки будут последовательно смещаться в цикле, стоит сделать две согласованные нагрузки и слить результаты вручную, даже если palignr не является опцией. Даже равноценные нагрузки SSE не будут вас спасать, если они не разделены точно по середине.

В AMD это никогда не было проблемой, и проблема в основном исчезла в Nehalem, но там еще много Core2.

Ответ 3

В целом оценка скорости на современных процессорах чрезвычайно сложна. Это справедливо не только для неприглашенных доступов, но в целом.

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

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

Другое очень важное различие происходит, если нелицензированный доступ происходит через границы кешлайн. В общем случае доступ к кешу 2x может произойти для неравномерного доступа, реальное замедление - это если доступ пересекает границу кешины и вызывает пропущенную двойную кешировку. В худшем случае 2-байтовое невыровненное чтение может потребовать, чтобы процессор сбросил две кэшлины в память, а затем прочитал 2 chachelines из памяти. То, что перемещается множество данных.

Здесь также применяется общее правило оптимизации: первый код, затем измерение, тогда тогда и только тогда, когда есть проблема, выведите решение.