Всем здравствуйте.
Есть тут знатоки ассемблера для x86? В частности оптимизации под AVX2?
Мучаюсь с таким вот вопросом, надо просуммировать очень много 256 бит чисел (точнее сложить два 300 млн битных числа), загружаю их в AVX регистры и складываю командой
vpaddq, но она не распространяет переносы через границы 64 бит, это приходится делать вручную. И эта вот ручная работа занимает до чёрта много времени, 21 такт (при том что основное сложение всего 0.5-1 такт), в основном из-за тормознутости
vpermq (четырежды переставляющей бит переноса в нужную позицию), неспариваемости инструкций так как они все взаимозависимы по данным получаются и почти все ложатся в один порт запуска (AVX перестановщик). Фактически быстрее оказывается разложить 4 слова в отдельные регистры, сложить их последовательно (с выделением переносов) и собрать обратно в 256 бит слово. Мрак, сложить можно два 512 битных числа за такт, а потом 42 такта учитывать внутренние переносы в них.
Собственно вопрос, может кто что посоветует как побыстрее организовать распространение переноса по всему AVX регистру? Я могу переносы оставить в каждом 63-м (63-м, 127-м, 191-м, 255-м) бите, без ухода за разрядную сетку, сейчас так уже и делаю.
Пробовал гуглом искать варианты, не хватает терпения, первые десятки страниц сплошные общие слова и обзоры новых процессоров, а мой вопрос ближе к алгоритмам и оптимизации программ. Если что и встречается, то исключительно про реализацию длинной арифметики (и часто для задач шифрования), а там такты на сложениях особо не экономят, складывают по 64 или даже 32 бита и не парятся. Мне - это слишком долго, хочется сильно быстрее. Помогите идеями?
Может как-то не сдвигом выделять переносы, или не
vpermq их расставлять в нужные позиции (но других команд пересылок через 128 бит границу и нет почти) или уйти от зависимости по данным? Можно даже вдвое больше команд выполнять, но чтобы они спаривались и были с малой задержкой.
Задача коммерческого смысла не имеет, делается как хобби.