Обновить
26

Программист С++

3
Подписчики
Отправить сообщение
Для эмуляции есть способ. Где то находил в интернетах SDK для эмуляции. С практической точки зрения SDK интересно лишь для отладки.

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

Как пример: функция для умножения матрицы на вектор — станет медленнее, функция для умножения матрицы на массив векторов — имеет смысл.

Гибкий вариант есть здесь optimizing_cpp.pdf. Искать по: CriticalFunction_Dispatch.

При миграции с SSE на AVX (повышение разрядности инструкций), сможет с минимальными изменениями. В SSE регистр вмещалось 4 float, в AVX 4 double. Если на той же разрядности регистров нужен double, тогда придётся переписывать.

80 только FPU. SSE: 32*4=64*2=128bit, AVX: 64*4=32*8=256bit.
По сути точность несколько меньше, плата за производительность.
habr.com/post/418247/#comment_18922625
Пожалуй, лучше чем здесь я не отвечу.
Посмотрел. Да, это что мне нужно. Увы, ICC specific.
Согласен. Если бы компиляторы так умели, я бы точно не стал заморачиваться.
Я уверен, что всё равно найдутся несогласные. Но для меня это пройденный опыт, и я не хочу на нём останавливаться. Если вы считаете, что можете лучше с dpps, киньте сюда свою реализацию вычисления умножения с ней, которая будет лучше хотя бы 20 тактов (с учётом чтения матриц m/n и записью в результирующую матрицу r), и я публично признаю свою ошибку.
Кстати я понял почему так вышло. Я взял те самые 4*4*4 из текста, предназначенные для одного умножения во внутреннем цикле, и перенёс их на mulps, в котором 4 умножения.
В моём рабочем коде классов классе пишу вроде
__forceinline __m128 __vectorcall operator + (__m128 const) const noexcept;

Однако здесь всё итак работает хорошо. Всегда проверяю сгенерированный ассемблерный код. Насчёт *assume_aligned я посмотрю что это. Скорее всего то, чего мне сильно и давно не хватает. Но если оно linux/intel_compiler/… specific, то мне, к сожалению, не подойдёт.
Очень разумный вопрос. Статья по факту представляет чистый положительный опыт. Если собрать весь отрицательный, то она будет минимум в 3 раза больше. Конечно dpps я пробовал когда то. Не оправдала от слова совсем.

Когда SSE4.1 только рекламировали, я уже надеялся, что такая классная инструкция dpps всё упростит. И ждал. Но увы…

1. Она дорогая: 2 такта (и судя по всему не параллелится как mulps), то есть даже без учёта транспонирования, их надо 16 по 2 такта, получается 32!!! (IACA согласна)
1.1 dpps — 4 умножения, 3 сложения
1.2 mulps — 4 умножения, параллелится, это 8 умножений за такт, 16 за два такта, или, грубо, 8 умножений + 3 сложения за 2.5 такта
2. Одну матрицу надо предварительно трансформировать: dpps(строка M, столбец N)
3.1 дополнительная инструкция movss для извлечения результата и работа с памятью на уровне 1-го float
ИЛИ
3.2 дополнительный код для компоновки результата из 4 float в одном xmm

Не стоит думать об инструкции, как вещи в себе. Инструкции нужны данные, они должны быть в нужном представлении как на входе, так и на выходе.

По совокупности факторов её даже Intel не использует в своих примерах матричного умножения.
Спасибо за информацию. Тем более прав был old_bear, когда настаивал на замерах времени: habr.com/post/418247/#comment_18921601.
4096x4096 это по сути 4k экран. Тут уже SIMD + MT (multithreading). А у меня речь про чистый SIMD пока. А сама по себе задача интересная.
Спасибо!!! Как проглядел непонятно. Исправлю.
1. Да, верю. По опыту. Результаты как минимум коррелируют. Ну будут у меня цифры немного другие, сути это не меняет. А IACA разбирается в архитектуре Intel лучше меня уж точно.
2. Про реальный мир вы зря: я давно уже использую SIMD и тестирую и так, и так. Тут решил обойтись.
3. Не могу протестировать всё. У меня максимум AVX (i7-3770).
4. Это будет синтетика. Я уже отмечал, что тысячами матрицы я не умножаю.
5. Однако вы правы: пункт 4 имеет место быть, но IACA не может учитывать реальную работу с данными, памятью. Поэтому стоит написать. Интересно будет не только вам.
Конечно. Пока посмотреть можно тут: www.youtube.com/watch?v=gBp1PoWzeO8
Сначала писал статью. Потом понял, что одна не получится. Потом понял, что сразу всё писать сложно. Эта статья как раз вышла из неё. Решил посмотреть как пойдёт и будет ли интерес.
Если кратко, то: Quake2 1600x1200, MT (multythreaded), SSE3, i7-3770, 30 fps.
Переделываю с нуля под AVX. Цикл статьей планируется по SSE варианту.
Согласен. Пока набираюсь опыта. Собираю пожелания.

Информация

В рейтинге
Не участвует
Зарегистрирован
Активность