Войти
ПрограммированиеФорумОбщее

SIMD оптимизации (20 стр)

Страницы: 119 20 21 2226 Следующая »
#285
(Правка: 23:17) 23:16, 20 ноя. 2018

invis
Отлично, спасибо огромное !!!
Я поправил версию с интринсиками gcc по твоим советам, и она внезапно стала даже чуть быстрее x64 версии!
Так что весь ручной SSE/AXV можно смело в помойку! )

>>Хотя test_bits_any - это уже скорее выпендрёж, проще интринсик воткнуть.
Не, не, то что надо, спасибо! Ведь следующая цель -- сделать независимо от системы команд.


>>Вообще использование типизированных указателей в оригинальном коде - спорно, я бы юзал void* для load/store.
Неудобно, как тогда отличить загрузку vint8 от vfloat8 ?  Нужно явно каст делать.


#286
(Правка: 23:27) 23:27, 20 ноя. 2018

invis
> Может сделать смешанный подход - 2 пикселя в 8-компонентном векторе? Тем самым
> снижаем кол-во пограничных случаев, когда часть пикселей в треугольнике, часть
> снаружи, и заодно выкидываем перетасовку цветовых комнонент - все эти сдвиги и
> |, там что-то около 20 команд получается.

Наверное можно попробовать, но звучит как очень большой геморрой.
Я думаю что для начала сделаю векторизацию всего тайла 4x4, а не по строчкам.
Тогда кол-во пограничных случаев будет ещё меньше.

Я вот думаю ещё для 2D случая попробовать всё перевести в фиксированную точку и .... может получится ужаться в 16 бит на пиксел?
Тогда, пусть и менее точно будет работать, но можно одной AXV командой будет весь тайл 4x4 обрабатывать.

#287
(Правка: 23:53) 23:52, 20 ноя. 2018

FROL
Называть их "интринсиками gcc", ИМХО, не здраво. Vector extensions они.

> Не, не, то что надо, спасибо! Ведь следующая цель -- сделать независимо от системы команд.
Ну так казалось бы и сделать её fallback. А на x86 таки заюзать соответствующую инструкцию.

> Неудобно, как тогда отличить загрузку vint8 от vfloat8 ? Нужно явно каст делать.
У меня лично тупо load4i / load4f . Можно load<type>.

Выложить свою обёртку?

#288
23:59, 20 ноя. 2018

Как-то так:

+ Показать

#289
(Правка: 12:23) 12:21, 21 ноя. 2018

Класс, спасибо!

PS: а чего __builtin_shuffle не используешь?

#290
12:41, 21 ноя. 2018

FROL
> PS: а чего __builtin_shuffle не используешь?
Походу я про неё в тот момент был не в курсе (или из головы вылетело).

А то, что у тебя rcp внутри делает 1.0f/x - выглядит совсем странно.

#291
12:41, 21 ноя. 2018

FordPerfect
> А то, что у тебя rcp внутри делает 1.0f/x - выглядит совсем странно.

А как надо?

#292
12:45, 21 ноя. 2018

FROL
Ну, предполагается, что 1.0f/x ты и так сможешь написать.
А rcp - это именно быстрый аппроксимированный reciprocal, rcpps для x86.

#293
(Правка: 13:34) 12:46, 21 ноя. 2018

Кто-нибудь может объяснить, зачем замыкаться на одной платформе через платформозависимые __buildin_*?

А это что? И как это работает?
static inline simd4i min4i(simd4i a,simd4i b) {return a<b?a:b;}

Это функция-шутка я так понимаю?
static inline void store4i(void *p,const simd4i v) {std::memcpy(p,&v,sizeof(v));}
Это делается одной инструкцией процессора! Без memcpy.

Зачем по всему коду написано static inline в h файле? Это очень странная практика.

#294
12:51, 21 ноя. 2018

FordPerfect
Понял. Не, тут идея в том чтобы в алгоритме использовать rcp там где не требуется большая точность.
То есть явно указать что вот да, здесь можно схитрить.
А дальше, если есть платформенно-зависимая версия то там будет быстрый rcp, а если нет то мы будем довольствоваться точным вычислением.

#295
12:53, 21 ноя. 2018

Truthfinder
> Кто-нибудь может объяснить, зачем замыкаться на одной платформе через платформозависимые __buildin_*?
Под платформой подразумевается x86 или GCC?

> А это что? И как это работает?
https://gcc.gnu.org/onlinedocs/gcc/Vector-Extensions.html
https://godbolt.org/z/O1YYte

#296
(Правка: 13:37) 12:55, 21 ноя. 2018

FordPerfect
> Под платформой подразумевается x86 или GCC?

Какое отношение список неких id компилятора __buildin_* имеет к Intel x86?

> https://godbolt.org/z/O1YYte

Ничего себе как он умеет ...
А если он уже так умеет, нафига туда кривыми ручками лезть вообще непонятно? Что мешает сразу писать a + b < c + d? И не писать тонны static inline __buildin_.
Сейчас же получается подразумевается писать min4i(a + b, c + d); Ну тут либо в одну сторону, либо в другую тогда. Дожимать через min4i(add4i(a, b), add4i(c, d)).

Из имени RCP не следует её точность. Тогда уже как-то отметить надо, например:
vec rcp(vec v) { return 1.f / v; }
vec rcp_fast(vec v) { return rcp(v); }

#297
13:45, 21 ноя. 2018

FordPerfect

Ну кстати верное замечание было сделано. __buildin_ поддерживает NEON? Или в более общем варианте, __buildin поддерживает любой платформенный simd? Если да, то таки лучше __buildin.

#298
(Правка: 13:56) 13:55, 21 ноя. 2018

Truthfinder
> Какое отношение список неких id компилятора __buildin_* имеет к Intel x86?
Если ты про __builtin_* вместо интринсик - так это потому что я хотел CPU dispatch, а интринсики в этом случае геморройно подключать к GCC:
http://www.virtualdub.org/blog/pivot/entry.php?id=363
https://gist.github.com/rygorous/f26f5f60284d9d9246f6
Впрочем сейчас с этим, вроде, получше и в новых GCC (по крайней мере MinGW) интринсики нормально инклюдятся даже если -mno-sse.
Кстати, static примерно по той же причине, хотя это, возможно, уже излишне.
И да, код work in progress, я не утверждаю что там всё архитектурно хорошо.

> Это делается одной инструкцией процессора! Без memcpy.
memcpy тоже делается одной инструкцией процессора:
https://godbolt.org/z/8GZ9_7
И этот код - наименее геморройный способ к этой инструкции доступиться.

> А если он уже так умеет, нафига туда кривыми ручками лезть вообще непонятно?
Мне приятнее +, чем add, но приятнее min, чем тернарный оператор. Синтаксическое предпочтение. min - бинарная функция, всё-таки.

А, и да. Предполагается, что в финальном коде вместо #error Thine compiler sucketh будет класс-обёртка над интринсиками.
Как предлагается overload тернарный оператор?

> Из имени RCP не следует её точность.
Из имени - нет. Но это значение - вроде обычное использование термина. Интеловские инструкции называются именно rcpps и rsqrtps.
Впрочем, я не против rcp_approx.

#299
21:22, 21 ноя. 2018

FordPerfect
> > Это делается одной инструкцией процессора! Без memcpy.
> memcpy тоже делается одной инструкцией процессора:
> https://godbolt.org/z/8GZ9_7
> И этот код - наименее геморройный способ к этой инструкции доступиться.

Встретил похожий трюк в первый раз в PBRT --- и тоже не поверил, потом проверил -- действительно работает трюк )
Другое дело что ИМХО идеологически всё-таки более правильно использовать средство непосредственно для этого предназначенное -- reinterpret_cast.
Явное указание на то что в коде мы хотим получить. А memcpy всё-таки вызов функции.

Страницы: 119 20 21 2226 Следующая »
ПрограммированиеФорумОбщее