Как стать автором
Обновить

Комментарии 26

Снимаю шляпу!

Со снижением частоты — хорошо бы посмотреть на графики температуры. Скорее всего это окажется троттлинг.

>> Скорее всего это окажется троттлинг
Это не троттлинг, а фича — AVX (Turbo) Frequency
http://repnop.org/pd/slides/PD_Haswell_Architecture.pdf

Core detects presence of AVX instructions
AVX instructions draw more current & higher voltage is needed to sustain operating
conditions
Not all AVX instructions cause a drop in frequency. Scalar AVX unaffected.
Need to be at least 128 bit wide.
offtop: Чисто технически, троттлинг — это тоже фича, в принципе))
AVX — это не в два раза большее SSE, это два SSE!

Судя по контексту, тут (и ещё в некотором количестве заголовков и предложений) должно быть слово AVX2. И то, что его тут нет, сильно вводит в заблуждение тех, кто плохо ориентируется в SIMD-ах.

Нет, тут речь о любых 256-битных AVX инструкциях, т.е. AVX1 и AVX2.

Упс. Извините, мозг немного болеет гриппом вместе с остальным организмом и совсем забыл про то, что плавающая точка и в первом AVX-е 256-разрядная. Но целочисленные операции то ограничены 128 битами, так что не всё так однозначно. Может сделать какую-то ремарку на эту тему в тексте?
>> самый быстрый ресайз изображений
Самый быстрый по сравнению с чем?

1) Обрабатываете лишь один/два пикселя за раз.
2) Зачем-то переводите во float. Тут даже у 16 битной данных с фиксированной точкой хватит точности, не говоря уже о 32-bit, где точность выше float.
3) Работаете с AoS данными.
«Но проще закрыть на это глаза, чем пытаться максимально забить SSE-регистры полезными данными.»

Звучит совсем не как «самый быстрый ресайз изображений» в мире.
Там ещё нулевого пункта не хватает — «asm при написании кода не использовался».
Посмотрев пару раз, что делает компилятор с этими красивыми последовательностями интринсиков, я пользуюсь ими только в случаях крайней необходимости.
Можете посмотреть
https://godbolt.org/g/WRaEFL

.L4:
vpmovzxbd xmm0, DWORD PTR [rdx+rax]
vcvtdq2ps xmm1, xmm0
vbroadcastss xmm0, DWORD PTR [r8+rax]
add rax, 4
cmp r9, rax
vmulps xmm0, xmm0, xmm1
vaddps xmm2, xmm2, xmm0
jne .L4


Как написано, так и получилось
Беда в том, что это не всегда работает. Причём это «не всегда» довольно непредсказуемо наступает (вероятность сильно растёт при одновременном использовании 6 и более simd-регистров). Поэтому в какой-то момент я устал проверять дизасемблинг и перешёл на asm.
Самый быстрый по сравнению с чем?

Как вы понимаете, у меня нет возможности писать об этом в каждой части, поэтому специально для этого была написана часть 0.


Звучит совсем не как «самый быстрый ресайз изображений» в мире.

Совершенно верно. Звучит как «Как я сделал самый быстрый ресайз изображений. Часть 2». И каждое слово тут важно.

Если хочется максимальной производительности то, мне кажется, стоит вспомнить про кеш процессора. Брать пиксели из соседних строк, вероятно, будет не лучшим решением со стороны работы кеш системы, т.к. будет много промахов и дополнительных запросов к данным. В этом случае брать соседние пиксели из одной строки будет намного лучше.
Каюсь, не читал предыдущие статьи. Прочитал, осознал — здесь все несколько сложнее.
префетч + запись мимо кеша могут дать больше чем AVX2
Отчасти так происходит потому, что SIMD-подход объективно сложнее и не кроссплатформенный, а отчасти потому, что по нему мало информации.

SIMD очень простой и не понятно, какая информация о нём нужна.
Загрузили данные в регистры, выполнили команду, забрали данные. Просто операции не с одним числом, а с вектором.
Сложность SIMD — миф, непонятно откуда взявшийся.

В статье есть пример:


Заметьте, как много в SIMD-коде приходится делать явно при загрузке значений. В скалярном коде ничего этого нет, компилятор сам понимает, что раз мы умножаем 8-битное целое на float, то первое тоже нужно конвертировать в float.
То есть сложность SIMD в том, что надо загружать данные в том виде, в котором их ждет процессор?
Сложность SIMD в том, что нужно думать и руками делать:
1) загрузку переменных в регистры
2) манипуляции над регистрами
3) выгрузку результата из регистра в общую память

А развитие языков программирования всегда было направлено на то, чтобы программист забыл об этих низкоуровневых манипуляциях, и как следствие — как можно больше людей могли писать код. js, php, python, VM based languages — вот это все.
SIMD — это вообще Ассемблер.
Инстринкты — по сути кроссплатформенные обертки над ассемблерными командами. А на уровне ассемблеры векторные операции и скалярные по сложности работы не отличаются.
Ну и по собственному опыту:
не зная ассемблер, только закончив школу — без особых проблем открыл доки по SSE и перевел свою матлибу на SSE. Там же реально тупо всё: загрузил, выполнил, выгрузил. Ну просто вообще ничего сложного. Разве что сложное слово «регистр» всплывает.

НУ а вообще я прицепился к «сложно, потому что мало информации».
Ну я примерно это и имел ввиду. Просто само слово ассемблер некоторых людей вгоняет в ступор. И не низкоуровневые программисты привыкли мыслить переменными. То, что происходит под капотом — вгоняет в ступор.
Из моего опыта, сложность не в том, чтобы написать на SSE код, дающий правильный результат, а в том, чтобы этот код работал не на 5% быстрее скалярного, а на более существенную величину.
Именно так. ПОэтому большая часть прогеров и не заморачивается с векторными операцями.
Собственно я и сам в далеком 2006 году перевел мат либу на SSE, понял что это не дало вообще ничего. Не потому что плохо перевел, а потому что задачи не так уж часто дергают векторные операции, чтобы приорст был ощутимый. Как говорится оптимизировать надо не всё подряд, а bottle neck. А он очень редко в скорости выполнения операций над векторами. Если у нас не какая нибудь специфичная задача, типа того же ресайза изображений.
Интересно про учет гаммы узнать, насколько сильно замедлился бы ресайз если перед этим значения RGB возводить в квадрат, а после считать корень?
$ CC="ccache cc -msse4" python ./setup.py develop

Для gcc вы можете не использовать -msse4 и другие sse ключи компилятора, а использовать атрибут target у функции. Также можете отдать выбор по какой ветке идти с sse, avx или без для компилятора или libc, либо оставить выбор пути как у вас сейчас.

https://gcc.gnu.org/wiki/FunctionMultiVersioning

Используя препроцессор и проверку на gcc в нем, вы можете сделать что sse/avx будут работать автоматически в gcc, а для других компиляторов, надо указывать ключики.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Изменить настройки темы

Истории