В нашем 64-битном приложении много кода (в частности, в стандартных библиотеках), которые используют регистры xmm0-xmm7 в режиме SSE.
Я хотел бы реализовать быструю копию памяти с помощью ymm-регистров. Я не могу изменить весь код, который использует регистры xmm, чтобы добавить префикс VEX, и я также думаю, что это нецелесообразно, так как он увеличит размер кода, может заставить его работать медленнее из-за необходимости процессора для декодирования больших инструкций.
Я просто хочу использовать два регистра ymm (и, возможно, zmm - доступные в продаже процессоры, поддерживающие zmm, будут доступны в этом году) для быстрой копии памяти.
Вопрос: как использовать регистры ymm, но избегать переходных штрафов?
Будет ли штраф, если я использую только регистры ymm8-ymm15 (а не ymm0-ymm7)? В SSE первоначально было восемь 128-битных регистров (xmm0-xmm7), но в 64-битном режиме (xmm8-xmm15) также доступны для инструкций с префиксом без VEX. Тем не менее, я рассмотрел наше 64-битное приложение, и он использует только xmm0-xmm7, так как он также имеет 32-битную версию с почти тем же кодом. Выполняется ли штраф только тогда, когда CPU пытается использовать регистр xmm, который использовался ранее как ymm, и имеет один из более высоких 128 бит, отличных от нуля? Разве не лучше просто обнулить регистры ymm, которые я использовал после быстрой копии памяти? Например, я однажды использовал регистр ymm для копирования 32 байтов памяти - какой самый быстрый способ его обнулить? Является ли "vpxor ymm15, ymm15, ymm15" достаточно быстро? (AFAIK, vpxor может выполняться на любом из трех портов выполнения ALU, p0/p1/p5, а vxorpd может выполняться только на p5). Не было бы время обнулить его больше, чем получить его, чтобы просто скопировать 32 байта памяти?