советы по оптимизации при фиксировании значения в цикле

Для вашего массива длина массива равна 3 (например, name.length = 3). Но поскольку он хранит элемент, начинающийся с индекса 0, он имеет максимальный индекс 2.

Итак, вместо 'i ** & lt; = name.length' вы должны написать 'i & lt; ** name.length' чтобы избежать «ArrayIndexOutOfBoundsException».

1
задан james 16 January 2019 в 14:39
поделиться

2 ответа

Мой вопрос на практике в производственном коде, каков рекомендуемый подход для его оптимизации? Должны ли мы использовать встроенную сборку в коде C ++? Или, как это делал Чендлер, компилировать код C ++ в сборку, а затем оптимизировать ассемблер?

Для рабочего кода необходимо учитывать, что программное обеспечение может быть скомпилировано и связано в системе автоматической сборки.

Как бы вы хотели применить изменения кода к коду ассемблера в такой системе? Вы можете применить diff-файл, но он может сломаться, если изменятся настройки оптимизации (или другие), при переключении на другой компилятор или ...

Теперь осталось две опции: написать всю функцию в файле ассемблера (.s) или иметь встроенный код ассемблера внутри кода C ++ & ndash; последний, возможно, с преимуществом сохранения связанного кода в той же самой единице перевода.

Тем не менее, я бы позволил компилятору генерировать ассемблерный код один раз - ndash; с наивысшим доступным уровнем оптимизации. Этот код может затем служить (уже предварительно оптимизированной) основой для ваших оптимизаций, сделанных вручную, результаты которых затем должны быть вставлены обратно как встроенная сборка в исходный файл C ++ или помещены в отдельный исходный файл сборки.

0
ответ дан Aconcagua 16 January 2019 в 14:39
поделиться

Чендлер изменил вывод asm компилятора, потому что это простой способ провести одноразовый эксперимент, чтобы выяснить, будет ли изменение полезно , без выполнения всего того, что вы ' Обычно я хочу включить asm-цикл или функцию как часть исходного кода для проекта.

Генерируемый компилятором asm, как правило, является хорошей отправной точкой для оптимизированного цикла, но фактически сохранение всего файла как есть, не является хорошим или даже жизнеспособным способом фактически поддерживать реализацию asm цикла как части программы. , См. Ответ @ Аконкагуа.

Кроме того, он отрицает необходимость иметь какие-либо другие функции в файле, написанном на C ++, и быть доступным для оптимизации во время соединения.


Re: собственно фиксация:

Обратите внимание, что Чендлер только что экспериментировал с изменениями в не векторизованном коде и отключил развертывание + авто-векторизацию. Надеемся, что в реальной жизни вы можете выбрать SSE4.1 или AVX2 и позволить компилятору автоматически векторизовать с помощью pminsd или pminud для сжатия int со знаком или без знака до верхней границы. (Также доступно для элементов других размеров. Или без SSE4.1, только SSE2, может быть, вы можете 2x PACKSSDW => packuswb (без знака насыщения), а затем распаковать с нулями до 4 векторов меча элементы. (Если вы не можете просто использовать вывод uint8_t[]!)

И, кстати, в комментариях к видео, Чендлер сказал , что оказалось, что он допустил ошибку и эффект, который он видел, на самом деле не был связан с предсказуемым переходом по сравнению с cmov. Это могло быть следствием выравнивания кода, потому что изменение с mov %ebx, (%rdi) на movl $255, (%rdi) имело значение!

(Процессоры AMD, как известно, не имеют регистров чтения-остановок, как в семействе P6, не должны иметь проблем с сокрытием цепочки dep в cmov, связывающей хранилище с нагрузкой, против разрыва с предсказанием ветвления + спекуляцией за ветвью. )


Вы очень редко действительно захотите использовать рукописный цикл. Часто вы можете держать и / или обманывать свой компилятор, чтобы сделать asm более похожим на то, что вы хотите , просто изменив исходный код C ++. будущий компилятор может настраиваться по-другому для -march=some_future_cpu.

0
ответ дан Peter Cordes 16 January 2019 в 14:39
поделиться
Другие вопросы по тегам:

Похожие вопросы: