Я работаю над арифметикой для умножения очень длинных целых чисел (около 100 000 десятичных цифр). В рамках моей библиотеки я добавлю два длинных номера.
Профилирование показывает, что мой код работает до 25% его времени в подпрограммах add() и sub(), поэтому важно, чтобы они были как можно быстрее. Но я пока не вижу большого потенциала. Может быть, вы можете дать мне помощь, советы, идеи или идеи. Я проверю их и вернусь к вам.
До сих пор моя программа добавления выполняет некоторую настройку, а затем использует 8-разный развернутый цикл:
mov rax, QWORD PTR [rdx+r11*8-64]
mov r10, QWORD PTR [r8+r11*8-64]
adc rax, r10
mov QWORD PTR [rcx+r11*8-64], rax
Далее следуют еще несколько блоков с разными смещениями, а затем они петли.
Я попытался загрузить значения из памяти ранее, но это не помогло. Я думаю, это из-за хорошей предварительной выборки. Я использую четырехъядерный процессор Intel I7-3770 Ivy Bridge. Но я бы хотел написать код, который хорошо работает на любом современном процессоре.
Изменить. Я сделал несколько таймингов: он добавляет 1k слов примерно в 2,25 цикла/слова. Если я удалю АЦП, останутся только MOV, все равно потребуется около 1,95 цикла/слова. Таким образом, основным узким местом является доступ к памяти. Библиотека memcpy()
работает примерно в 0.65 циклах/словах, но имеет только один вход, а не два. Тем не менее, это намного быстрее из-за использования регистров SSE, я думаю.
Некоторые вопросы:
- Полезно ли использовать структуру "загрузить, загрузить, добавить, сохранить" или "загрузить, добавить в память"? Пока мои тесты не показали никаких преимуществ.
- Как обычно, от SSE (2,3,4) не ожидается никакой поддержки?
- Не влияет ли адресация (масштабированный индекс плюс базовая плюс смещение)? Вместо этого я мог бы использовать
ADD r11, 8
. - Как насчет разворота цикла? Я читал, что разворачивание было плохо для архитектуры Sandy Bridge (Agner Fog http://www.agner.org/optimize/). Это должно быть предпочтительным или избегать?
- (Изменить) Могу ли я использовать регистры SSE для загрузки и хранения слов в больших кусках из памяти и эффективного обмена словами с регистрами общего назначения и SSE-регистрами?
Я высоко ценю любые комментарии.