quinta-feira, junho 25, 2009

Operações com vetor usando SSE

Olá pessoal depois de fuçar com o vertex_program/fragment program, descobri o SIMD
(Single Instruction, Multiple Data), o que isso siginifica.

imagine que temos o vetor a = [x,y,z,w] e b = [x,y,z,w], quando vamos fazer uma operação do tipo c = a * b o processo seria este.

c.x = a.x * b.x;
c.y = a.y * b.y;
c.z = a.z * b.z;
c.w = a.w * b.w;

o disassembly deste processo no MSVC++ 2005

c.x = a.x * b.x;
0041197E fld dword ptr [a]
00411981 fmul dword ptr [b]
00411984 fstp dword ptr [c]
c.y = a.y * b.y;
00411987 fld dword ptr [ebp+10h]
0041198A fmul dword ptr [ebp+20h]
0041198D fstp dword ptr [ebp-10h]
c.z = a.z * b.z;
00411990 fld dword ptr [ebp+14h]
00411993 fmul dword ptr [ebp+24h]
00411996 fstp dword ptr [ebp-0Ch]
c.w = a.w * b.w;
00411999 fld dword ptr [ebp+18h]
0041199C fmul dword ptr [ebp+28h]
0041199F fstp dword ptr [ebp-8]

o gcc é bem mais inteligente que isso (to no maldito windows agora)

a mesma operação usando SSE, nos dois caso eu não coloquei a parte responsável por pegar os parametros passados p/ a função e o seu retorno.
o abaixo foi escrito p/ o nasm

mov eax, [ebp+0x8] ;parametro 1 a
mov ebx, [ebp+0xc] ;parametro 2 b
mov ecx, [ebp+0x10] ;parametro 3 c

movups xmm0, [eax] ;coloca eax em xmm0
movups xmm1, [ebx] ;coloca ebx em xmm1
mulps xmm0, xmm1 ; xmm0 = xmm0 * xmm1
movups [ecx], xmm0 ;move xmm0 ecx (c)

creio que iriamos economizar alguns ciclos de processamento, então SSE é isto fazer operações com registradores de 128bits (16 bytes).

pra mais informações na comunidade tem bastante informação, os manuais da intel IA-32 2A e IA-32 2B tem o conjunto de instrução completo.

o 3DNow da amd e o altiVec do PowerPC tem o mesmo propósito, até o ARM tem um conjunto de instruções vetorias, você pode ser bem criativo ao usar esse conjunto de instruções, por exemplo o memcpy copia 4 bytes de cada vez (ao menos no header que eu vi), usando registradores de 128bits poderiamos mover 16bytes por vez, interessante não.

coloquei exemplos no link : http://www.mediafire.com/?sharekey=75c36d37bd6d2c0a391d7d881749d3a7e04e75f6e8ebb871

matematica.zip -> VC++ 2005
vectors.zip -> GCC + nasm

uma curiosiade é que este é o segredo do PS3 (CELL/B.E) ele tem um porcessador PowerPC (PPE) e 6 processadores (SPE), atualmente o Top 1 da top500.org o RoadRunner tem alguns milhares deste (CELL/B.E).

se eu falei alguma besteira favor me corrigir.

veja a Parte II.

Obrigado.

2 comentários:

NeoStrider disse...

O mais legal?
cada integradora de ARM faz sua própria extensão. Então se vc quer se especializar em ARM, tem que estudar bagarai.

É a vida...
Kudos, meu camarada. Ta mandando muito bem!

Gabriel disse...

você ainda pode usar os intrisics do gcc.