2014-09-06 3 views
1

Я работаю над некоторым кодом, который предназначен для работы на x86 в 32-битном режиме. В этом режиме я понимаю, что у меня есть только 8 SIMD/AVX2-регистров (YMM0-7), с которыми можно свободно работать. Тем не менее, некоторые из моих векторных подпрограмм в одиночку иногда используют больше, чем это количество регистров одновременно (что означает, что они все еще нужны где-то в дороге - в основном не так уж и поздно).Какое влияние влияет на экспорт регистров на стек?

Я понимаю, что компиляторы будут экспортировать старые регистры в стек памяти, когда они не могут найти неиспользуемые регистры. Но насколько это влияет на производительность? (например, в цикле на экспорт/импорт позже). Могу ли я доверять стеке, в основном, находящемуся в L1-D-Cache (с задержкой в ​​2 цикла в Haswell) или есть существенное влияние на производительность, позволяющее избежать таких передач с регистром-памятью (и наоборот)?

До сих пор я не мог найти ответы на эту тему, тем более, что регистры продолжают становиться все больше и больше (1 Cacheline за регистрацию на предстоящей платформе Skylake). Было бы неплохо, если бы вы могли дать источники, если вы ответите.

+3

Ваш код будет медленнее, конечно. Если вы хотите узнать, насколько просто прокомментируйте свой код, сравнивая 32-битную и 64-битную версии. Только ты можешь это сделать. –

+0

Из любопытства. Почему вы ограничены 32-битным режимом? Core2 вышел почти девять лет назад. А так как Nehalem (2008) macro op fusion работает в 64-битном режиме. AVX512, который выйдет в следующем году, будет иметь 32 AVX512 регистра в 64-битном режиме и только 8 в 32-битном режиме. Почему вы ограничиваете свой код только 32-битным режимом? –

+0

Я согласен с вами обоими. Похоже, мне нужно сравнить его, чтобы проверить, лучше ли корректировать мои инстрики. Требуется 32-разрядная поддержка, поскольку некоторые рабочие станции все еще работают с 32-разрядной операционной системой. Вопрос будет таким же, будь то его 8 или 16 регистров, только менее суровый. –

ответ

1

Всегда есть воздействие на память.

Запись, как правило, медленная. Однако, если вы попали только в кеш L1, он близок к мгновенному (почти так же, как копирование регистра на другой). Если вы нажмете L2 или L3, это будет медленнее, но все же очень быстро. Если вы нажмете фактическую память, это «мертво» медленно (в сравнении). Поэтому, если ваш кеш L1 составляет 12 КБ, вы можете иметь до 12 КБ данных в своем стеке и все еще работать очень быстро (хотя помните, что кэш разделяется между вашими данными и код, который вы используете, это может быть 6 Кбайт кэша команд и 6 Кбайт данных, включая стек.)

Основная проблема, с которой вы столкнетесь, - сколько памяти вы работаете. Если ваши входные данные очень большие, это будет иметь наибольшее влияние. Особенно, если вы не можете загружать входные данные потоковым способом, для которого процессоры хорошо оптимизированы. (прочитайте X байтов из (eax), сделайте eax + X, затем повторите).

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

В качестве еще одной детали компиляторы видят стек как структуру, определенную из набор всех локальных переменных, необходимых в функции. Поэтому доступ к стеклу очень похож на доступ к структуре.

+0

Какая микросхема x86 с AVX2 имеет ** объединенный ** L1 кеш 12kb? Кроме того, он называется «указатель кадра» или «базовый указатель», а не «буфер кадров». – EOF

+0

Я буду использовать C/C++ в сочетании с avx intrinsics. Чтобы стать яснее: это память, используемая для сохранения регистров (стек) «горячая» (находящаяся в L1), например. привыкаешь почти все время?Теоретически, разработчики компиляторов должны были реализовать его таким образом, но я не уверен, потому что его легко заполнить многие кешины с помощью регистров avx, особенно когда он использует ориентированные магазины. –

+2

Да, в этом смысле 99,9% времени ваш стек будет «горячим». Это будет зависеть от операционной системы больше, чем от компилятора (т. Е. Вы можете заставить память стека всегда записываться в ОЗУ). Компилятор может быть проблемой, если он распространяет данные «более чем необходимо», но это вряд ли проблема. То, что вы можете ударить, - это чтение новых данных, которые заменяют ваш стек в кеше L1. Теперь замечательная инструкция с внутренними инструкциями заключается в том, что вы можете использовать метки для регистров, и компилятор будет автоматически связывать регистр CPU, давая ему возможность еще больше оптимизировать ситуацию. –

Смежные вопросы