Просто потому, что у вас есть конвейер, никоим образом не означает, что он всегда будет использоваться эффективно. Как и добавление кеша, любой из них может стоить вам производительности, а не улучшать производительность. Поэтому нет никаких оснований предполагать, как бы «современный» ваш процессор, что вы всегда будете получать магические характеристики. Проблема начинается с вашего кода, это ваше приложение по какой-то причине, как вы пишете свое приложение, на каком языке вы используете какой компилятор вы используете, какие параметры компилятора вы используете, - это первые шаги в производительности, а затем платформа, RAM, кеш, диск, операционная система и т. д. все играют определенную роль. Прошло много лет с тех пор, как процессор стал узким местом, предполагая, что вы можете прокормить процессор так быстро, как он может потреблять, и предполагая, что последовательности команд дружественны к конвейеру, и у вас нет доступа к данным, а затем вы можете кричать, но реальность Процессор тратит много времени на ожидание подачи данных или инструкций. Вы можете написать очень простые тесты, даже малые, как два цикла команд, и увидеть, что производительность сильно варьируется в зависимости от различных факторов, характера выборки процессора, выравнивания, заставляющего его извлекать гораздо больше, чем нужно, перемещая выравнивание к чувствительной области строки кэша может привести к чтению дополнительной строки кэша. И это всего лишь пара/несколько инструкций, подумайте о том, сколько инструкций используется вашим приложением. Затем смешайте доступ к данным с этим. Бенчмаркинг - это несколько бесполезная задача, отличная от того, чтобы показать, что она действительно не означает ничего, кроме того, что вы можете манипулировать результатами, чтобы что-то выглядело хорошо или плохо.
В вашем случае вы просто не пишете свой код, чтобы быть дружелюбным к компилятору, чтобы он выполнялся, скорее всего, ваши обращения к данным, как вы структурировали свои данные (возможно, используя массивы байтов вместо больших массивов, используя структуры с предметы разного размера и т. д.), не дай бог разбить ваши данные на мощность двух кратных границ границ кеша.
Начните настройку своих данных или кода, измените функции поддержки в исходном коде, у вас может быть функция a, b, c, определенная в этом порядке, измените порядок a, c, b, как это изменит производительность, если вообще ? Добавьте фиктивную глобальную функцию рядом с началом вашего проекта (или зайдите в ремешок для загрузки и добавьте или удалите nops), возможно, встроенный, затем два, а затем три, а затем четыре и т. Д. Или другие аналогичные безопасные инструкции в этой фиктивной функции. Измените размер ваших переменных, измените размер элементов массива, если это возможно, перестройте порядок переменных, определенных в структурах. Один или все из них плюс много других вещей могут повлиять на результаты вашей работы.
Нижняя линия, имеющая современный процессор, не имеет ничего общего с часами на каждую усредненную инструкцию для любой случайной программы. Вы хотите получить много инструкций за такт, за которые вы должны работать (и нечего предполагать, что как только вы нажмете сладкое пятно на своем компьютере, вы перенёте эту программу на другой совместимый компьютер, который программа там выполняет, это может быть собака медленнее на других подобных машинах класса и быть быстрым на одном).
Обход списка включает в себя цепи зависимостей при доступе к памяти, а образы кэша L1 обычно имеют задержку в три или четыре цикла в современных высокопроизводительных ядрах. Выполнение вне порядка помогает, когда есть операции, которые не зависят от ожидающих результатов. –