Ответ 1
Глядя на ядро, созданное ghc-7.2.2, встраивание хорошо работает. Что не так хорошо работает, так это то, что на каждой итерации пара значений Word32
сначала распаковывается, выполняет работу, а затем переустанавливается для следующей итерации. Unboxing и re-boxing могут стоить удивительно большое количество времени (и распределение).
Вероятно, вы можете избежать этого, используя Word
вместо Word32
. Вы не могли бы использовать rotate
из Data.Bits, но вам придется реализовать его (не сложно), чтобы он работал и на 64-битных системах. Для a'
вам придется вручную маскировать высокие бит.
Еще одна точка, которая выглядит субоптимальной, заключается в том, что в каждой итерации t
сравнивается с 19, 39 и 59 (если она достаточно большая), так что тело цикла содержит четыре ветки. Вероятно, это будет быстрее, если вы разделите iterateBlock'
на четыре петли (0-19, 20-39, 40-59, 60-79) и используйте константы k1,..., k4 и четыре функции f1,..., f4 (без параметра t
), чтобы избежать ветвей и иметь меньший размер кода для каждого цикла.
И, как сказал Томас, использование списка для данных блока не является оптимальным, вероятно, поможет и вспомогательный массив/вектор Word.
С шаблонами ударов ядро выглядит намного лучше. Остаются две или три менее идеальных точки.
(GHC.Prim.narrow32Word#
(GHC.Prim.plusWord#
(GHC.Prim.narrow32Word#
(GHC.Prim.plusWord#
(GHC.Prim.narrow32Word#
(GHC.Prim.plusWord#
(GHC.Prim.narrow32Word#
(GHC.Prim.plusWord#
(GHC.Prim.narrow32Word#
(GHC.Prim.or#
(GHC.Prim.uncheckedShiftL# sc2_sEn 5)
(GHC.Prim.uncheckedShiftRL# sc2_sEn 27)))
y#_aBw))
sc6_sEr))
y#1_XCZ))
y#2_XD6))
Посмотрите все эти narrow32Word#
? Они дешевые, но не бесплатные. Нужно только самое внешнее, может быть немного урожая путем ручного кодирования шагов и использования Word
.
Затем сравнения t
с 19,..., они появляются дважды, один раз для определения константы k
и один раз для преобразования f
. Сравнения сами по себе дешевы, но они вызывают ветки и без них, возможна дальнейшая инкрустация. Я ожидаю, что здесь тоже можно получить немного.
И все же, список. Это означает, что w
не может быть распакован, ядро может быть проще, если w
были недоступны.