Ответ 1
Это просто ограничение в микро-архитектуре вашего процессора Intel Haswell и нескольких предыдущих 1 процессоров. Он был исправлен для tzcnt
и lzcnt
как и для Skylake, но проблема остается за popcnt
.
В этих микроструктурах операнд назначения для tzcnt
, lzcnt
и popcnt
рассматривается как входная зависимость, хотя и семантически это не так. Теперь я сомневаюсь, что это действительно "ошибка": если бы это был просто надзор, я ожидал, что это будет исправлено в одной из нескольких новых микро-архитектур, выпущенных с момента ее появления.
Скорее всего, это компромисс дизайна, основанный на одном или обоих из следующих двух факторов:
-
Аппаратное обеспечение для
popcnt
,lzcnt
иtzcnt
вероятно, все совместно с существующими инструкциямиbsf
иbsr
. Теперьbsf
иbsr
действительно имели отношение к предыдущему целевому значению на практике 2 для специального случая ввода всех бит-ноль, так как в этом случае чипы Intel оставили цель немодифицированной. Поэтому вполне возможно, что простейшая конструкция комбинированного оборудования привела к тому, что другие аналогичные инструкции выполнялись в одном и том же подразделении, наследующем одну и ту же зависимость. -
Подавляющее большинство инструкций ALU из двух операндов x86 зависят от операнда-адресата, поскольку он также используется как источник. Три затронутые инструкции несколько уникальны тем, что они являются унарными операторами, но в отличие от существующих унарных операторов, таких как
not
иneg
, которые имеют единственный операнд, используемый в качестве источника и адресата, у них есть разные исходные и целевые операнды, что делает их поверхностно похожими для большинства инструкций с 2 входами. Возможно, схема переименования/планировщика просто не отличает особый случай этих унарных с двумя регистрами-операндами по сравнению с подавляющим большинством простых разделенных исходных/целевых инструкций с двумя входами, которые не имеют этой зависимости.
Фактически, для случая popcnt
Intel выпустила различные ошибки, охватывающие проблему ложной зависимости, такую как HSD146 для Haswell Desktop и SKL029 для Skylake, который гласит:
Инструкция POPCNT может занять больше времени, чем ожидалось
Проблема Выполнение команды POPCNT с 32 или 64-битным операндом может быть задерживается до тех пор, пока не будут выполнены предыдущие независимые инструкции.
Последствия Программное обеспечение с использованием инструкции POPCNT может иметь более низкую производительность, чем ожидалось.
Обход проблемы Не указано
Я всегда считал этот необычный случай необычным, так как на самом деле он не идентифицирует какой-либо функциональный дефект или несоответствие спецификации, что имеет место, по существу, для всех других ошибок. Intel действительно не документирует конкретную модель производительности для механизма выполнения OoO, и на протяжении многих лет появилось и исчезло множество других "gotchas" производительности, многие из которых имеют гораздо больший эффект, что это очень незначительная проблема, t задокументировать в ошибках. Тем не менее, это, возможно, дает некоторые доказательства того, что это можно считать ошибкой. Как ни странно, erratum никогда не расширялся, чтобы включать tzcnt
или lzcnt
, которые имели такую же проблему, когда они были введены.
1 Ядро tzcnt
и lzcnt
появилось только в Haswell, но проблема существует и для popcnt
, которая была введена в Nehalem, но проблема ложной зависимости возможно только существует для Sandy Bridge или позже.
2 На практике, хотя это не документировано в документах ISA, поскольку результат для ввода с нулевым значением был undefined в руководствах Intel. Однако большинство или все чипы Intel реализовали поведение, так как оставляя регистр назначения неизменным в этом случае.