Свежие комментарии

Title Comment
а разве они уже умеют 1 блоком делать операцию над 256 бит в

а разве они уже умеют 1 блоком делать операцию над 256 бит вектором за раз ?
Вроде ж писали, что регистры по 256, но каждую половинку по факту обрабатывает свой блок.

Только так, как вы

Только так, как вы предлагаете - ничего не получится, увы.
Ну вот представьте, что у нас в первых 4 элементах d содержится {1,2,3,4}.
Первый элемент результата будет равен:

  • Правильный ответ: 1*0.17 + 2*0.22 + 3*0.33 + 4*0.44 = 3.36
  • Ваш вариант: 1*0.17 + 1*0.22 + 1*0.33 + 1*0.44 = 1.16
Ага, действительно

Ага, действительно интересно.

Я был уверен, что AVX-вариант умножает вектора длиной 8, но посмотрел в reference - нет, две половинки по 4.

Сделаю обязательно. Плюс, сделаю обязательно векторный вариант с транспонированными матрицами, как 256-битный, так и 128-битный.

Надо бы еще clang/llvm под виндой развернуть....

Большое спасибо за

Большое спасибо за приведенные измерения.

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

Как измениться производительность intrinsic варианта на Core-i7, если поменять
_mm_dp_ps на _mm256_dp_ps
_mm_blend_ps на _mm_blend256_ps

То-есть насколько вырастить производительность если мы совсем на AVX переедем и будет обрабатывать по 8 float за проход? А то слухи разные ходят... от 0% до 200% роста.

Срок хранения на флэшке?

Есть данные сколько времени современные флэшки хранят информацию?
В свое время было не более пяти лет, в течении которых будет происходить утечка заряда и всё...

Сейчас наверное больше, но нужно будет создавать оптимальные условия. Появляется еще одна аналогия со слайдами - не только сливер и стоимость, но и отдельный "холодильник" для хранения. :)

Да, с транспонированной

Да, с транспонированной матрицей конечно должно быть быстрее. Я пощупаю и расскажу.

А проход по инициализированным (т.е. без page fault) пикселям должен быть примерно одинаковый каждый раз, массив *много* больше кэша (для гигапикселя - на три порядка).

М-да. У меня gcc 4.6.1 и

М-да. У меня gcc 4.6.1 и брать елемент по индексу в векторе умеет.
На моем Core2 Quad Q9500 @ 2.83GHz, 64bit

С и без union-ом код разный получаеться

С union v4u

.L3:
movaps (%rdi,%rax), %xmm0
movl $0x00000000, -12(%rsp)
movaps xmat(%rip), %xmm1
mulps %xmm0, %xmm1
movaps %xmm1, -72(%rsp)
movaps xmat+16(%rip), %xmm1
mulps %xmm0, %xmm1
mulps xmat+32(%rip), %xmm0
movaps %xmm1, -56(%rsp)
movaps %xmm0, -40(%rsp)
movss -72(%rsp), %xmm0
addss -68(%rsp), %xmm0
addss -64(%rsp), %xmm0
addss -60(%rsp), %xmm0
movss %xmm0, -24(%rsp)
movss -56(%rsp), %xmm0
addss -52(%rsp), %xmm0
addss -48(%rsp), %xmm0
addss -44(%rsp), %xmm0
movss %xmm0, -20(%rsp)
movss -40(%rsp), %xmm0
addss -36(%rsp), %xmm0
addss -32(%rsp), %xmm0
addss -28(%rsp), %xmm0
movss %xmm0, -16(%rsp)
movaps -24(%rsp), %xmm0
movaps %xmm0, (%rdi,%rax)
addq $16, %rax
cmpq %rsi, %rax
jne .L3

Без union-а код, как по мне, получше, но черт его знает как быстро инструкция extractps отрабатывает.


.L8:
movaps (%rdi,%rax), %xmm1
movl $0x00000000, -12(%rsp)
movaps xmat(%rip), %xmm3
movaps xmat+16(%rip), %xmm2
mulps %xmm1, %xmm3
mulps %xmm1, %xmm2
mulps xmat+32(%rip), %xmm1
extractps $1, %xmm3, %edx
movaps %xmm3, %xmm0
movd %edx, %xmm4
addss %xmm4, %xmm0
extractps $2, %xmm3, %edx
movd %edx, %xmm4
extractps $3, %xmm3, %edx
movd %edx, %xmm3
extractps $1, %xmm2, %edx
addss %xmm4, %xmm0
movd %edx, %xmm4
extractps $2, %xmm2, %edx
addss %xmm3, %xmm0
movd %edx, %xmm3
extractps $3, %xmm2, %edx
movss %xmm0, -24(%rsp)
movaps %xmm2, %xmm0
addss %xmm4, %xmm0
movd %edx, %xmm4
extractps $1, %xmm1, %edx
movd %edx, %xmm2
extractps $2, %xmm1, %edx
addss %xmm3, %xmm0
movd %edx, %xmm3
extractps $3, %xmm1, %edx
addss %xmm4, %xmm0
movd %edx, %xmm4
movss %xmm0, -20(%rsp)
movaps %xmm1, %xmm0
addss %xmm2, %xmm0
addss %xmm3, %xmm0
addss %xmm4, %xmm0
movss %xmm0, -16(%rsp)
movaps -24(%rsp), %xmm0
movaps %xmm0, (%rdi,%rax)
addq $16, %rax
cmpq %rsi, %rax
jne .L8

В итоге я предлагаю переписать функцию, вот таким вот образом. Все заметно быстрее начинает бегать.

typedef float __v4sf __attribute__ ((__vector_size__ (16)));
__v4sf xmat2[4] = {{0.17f, 0.55f, 1.01f, 0.0f}, {0.22f, 0.66f, 1.02f, 0.0f}, {0.33f, 0.77f, 1.03f, 0.0f}, {0.44f, 0.88f, 1.04f, 0.0f}}; // weights are transposed

void fdotp_vec3 (__v4sf *d, int sz)
{
__v4sf rr0,rr1,rr2,rr3;
for(int i=0;i

Здесь и без слов понятно, что все на порядок быстрее

.L12:
movaps (%rdi,%rax), %xmm1
movaps xmat2(%rip), %xmm0
movaps xmat2+16(%rip), %xmm2
mulps %xmm1, %xmm0
mulps %xmm1, %xmm2
addps %xmm2, %xmm0
movaps xmat2+32(%rip), %xmm2
mulps %xmm1, %xmm2
mulps xmat2+48(%rip), %xmm1
addps %xmm2, %xmm0
addps %xmm1, %xmm0
movaps %xmm0, (%rdi,%rax)
addq $16, %rax
cmpq %rsi, %rax
jne .L12

Кстати, я также думаю что первый проход по массиву пикселей будет всегда медленней всех последующих. Было бы хорошо проверить.

Вот занесло на dealxtreme и я эту лягушку нашел: http://www

Вот занесло на dealxtreme и я эту лягушку нашел:

http://www.dealextreme.com/p/usb-powered-universal-cell-phone-battery-ch...

Два бакса стоит!

Да как-то не вижу я ее в

Да как-то не вижу я ее в 4.6.2:

__v4sf rr0,rr1,rr2,res;
....
res[0] = rr0[0]+rr0[1]+rr0[2]+rr0[3];

Дает: dotp.cpp:172:7: error: invalid types '__v4sf {aka __vector(4) float}[int]' for array subscript

Возможно, я готовлю как-то не так, примеров на вебе как-то совсем мало вменяемых.

$ gcc -v
gcc version 4.6.2 20110826 (prerelease) (FreeBSD Ports Collection)

Вот clang так понимает, только разницы никакой:
dotp_vec(): 130.9 Mpix/sec (15283.4 msec)
dotp_vec2(): 130.6 Mpix/sec (15312.4 msec)

(_vec2 - это без union)

Лично мне, векторный код gcc

Лично мне, векторный код gcc кажеться кривоватым.

Ну, нафига ты вводил новый union тип v4u...... Ты же обгадил всю малину для gcc оптимизатора.

А к елементам __v4sf можна обратиться просто по индексу без этих костелей. Правда эта фичя только в 4.6.0 появилась.

typedef float __v4sf __attribute__ ((__vector_size__ (16)));

__v4sf v;
v[0] = 1.0;

Ну вот у меня в посте ссылка ("например такой") на какой-то

Ну вот у меня в посте ссылка ("например такой") на какой-то китайский универсальный зарядник для 3.7 и 7.4 с питанием от 5В и от 12.
Пока не пробовал.

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

Вроде его Вампирчик всегда продавал как свою железку ? Может

Вроде его Вампирчик всегда продавал как свою железку ?
Может я и перепутал, конечно, но от вампирчиковских преобразователей впечатления удручающие.
слово "термостабилизация" разработчикам неведомо, а литию для зарядки нужно 50мВ точности.

Айфону нужно 700мА, насколько я помню, а многие USB-зарядки дают только 500, в отличие от вампирчиковских, которые умеют 1.5А

Вопрос про то, чем заряжать сами аккумуляторы, вне устройств, которые умеют заряжать, типа айфона, Thuraya и пр.

"лягушка" - это не "от вампирчика", это чистый и незамутненн

"лягушка" - это не "от вампирчика", это чистый и незамутненный китай.

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

"Зарядное устройство Лягушка зарядило Турайю "на одну палку"

"Зарядное устройство Лягушка зарядило Турайю "на одну палку", зажгло лампочку "зарядка закончена" и приказало долго жить"

Я ещё в прошлом обсуждении писал, что электроника у Вампирчика (ну и MobiPower, соответственно) "на уровне детсада" по надежности и качеству исполнения.

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

Ну круто, а то asm встраивать

Ну круто, а то asm встраивать везде по своему надо (AT&T/etc). В VisualStudio x64 asm вообще нельзя встраивать в код, приходится отдельно линковать..

gcc понимает _mm (и набор

gcc понимает _mm (и набор #include тот же).

Они транслируются в _builtin_ через дефайны.

Update: и clang - тоже.

Т.е. fdotp_sse из поста - транслировалась всеми четырьмя компиляторами (и давала правильный результат!)

Ну да, оно все раздражает. И

Ну да, оно все раздражает. И трансляция из регистров в имена переменных и разный порядок операндов в командах у gcc и Intel/MS.

С vex-командами (трехадресными) вообще начало сносить крышу:

vdpps xmm11, xmm5, xmm0, 241
против
vdpps $241, %xmm3, %xmm0, %xmm1

Блин.

Покрайней мере у ICC и Visual

Покрайней мере у ICC и Visual C++ они одинаковы, про gcc незнаю точно но мне кажется тоже самое.

Такой код бы был хорошо

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

intrinsic вроде у каждого компилятора свои, или нет?

Так и приходится, только в

Так и приходится, только в Visual C++. Долго переписывать с assembler'а на intrinsic'и. Где-то видел скрипт на питоне преобразующий ассемблерные вставки на intrinsic'и но что то найти его никак не могу.

Его на intrinsic'и

Его на intrinsic'и переписывать не очень удобно, мне приходиться для многих инструкций по справке искать ее название в intrinsic'ах.
Iscp хорош, надеюсь в нем уже исправили багу что при target SSE2 в аутпут попадали и SSE4 инструкции.

Жаль нету компиляторов/утилит

Жаль нету компиляторов/утилит который бы по C коду генерировал бы черновой векторизованный вариант для нужной версии SSE для дальнейшей ручной оптимизации

gcc -S
или просто disasm - берите и пилите...

А чем просто ассемблерный

А чем просто ассемблерный вывод нехорош?

Ну и ispc есть, для векторного случая (т.е. сильно векторизуемых данных) - в самый раз.

Intrinsics

Ссори за оффтоп. Жаль нету компиляторов/утилит который бы по C коду генерировал бы черновой векторизованный вариант для нужной версии SSE для дальнейшей ручной оптимизации. Такой код бы был хорошо портируемый и с хорошей производительностью, хотя скорее всего не с оптимальной.

OpenCL выиграет только если

OpenCL выиграет только если надо "10 раз".

OpenCL

> Кормились 1 миллиардом пикселей 10 раз. Времена исполнения каждого сниппета получаются в диапазоне 3.5-20 секунд, что более чем достаточно.
Так и чешутся руки переписать на OpenCL. Просто помоему идеально ложится, если удастся как можно больше сделать операций на GPU до пересылки результата обратно на CPU.
Я читал в предыдущем посте почему это не сделано.

Ну вот я смотрю в книгу в

Ну вот я смотрю в книгу в листинг, вижу разницу
а) в movups/movaps
б) в обработке итераций цикла (как и для i7-1)

Ну не должна быть такая разница от инвариантов. Хрен его знает, конечно.

Заметно меньшая эффективность

Заметно меньшая эффективность компилятора Intel для "ручного кода" на AVX-процессоре объясняется банально: для load/store используется [v]movups (невыровненые данные) вместо [v]movaps.

Так на i7 вроде без разницы movups или movaps (всмысле по скорости). Я по-моему даже тест делал, хотя могу и ошибаться.

quick google показал: http://www.google.ru/url?sa=t&source=web&cd=9&ved=0CGsQFjAI&url=http%3A%...

"Intel SSE included movups (on previous IA-32 and Intel 64 processors,
movups) was not the best way to load data from memory. Now, on
Intel Core i7 processors, movups and movupd are as fast as movaps
and movapd on aligned data. So, when the Intel Compiler uses /
QxSSE4.2 it removes the if condition to check for aligned data
speeding up loops and reducing the number of instructions to
implement."

Ну так "производительность не переносится". Ну разве только

Ну так "производительность не переносится".
Ну разве только в виде библиотек, заранее написанных на ассемблере, вроде IPP.

Я тут, к удивлению своему, обнаружил, что SSE4.1 (в виде dpps и blendps) есть не на всех Core2. На макбуке 4-летнем (2007-й) процессор T7500, а на нем только SSE3.

Я с удивлением недавно

Я с удивлением недавно заметил что VC++ автоматически анролит циклы с небольшим константным количеством итерации. Возможно он и без прагмы цикл unroll'ит :-).

Pages

Subscribe to comments_recent_new