SIMD 연산은 C언어에서 += 연산과 유사한 동작을 한다
예)
int a,b;
a += b;
와 유사한 연산을 한다
B : byte
W :word
D : double word = 4 byte
Q : quad word = 8 byte
S는 signed US 는 unsiged 를 나타냄으로
PADDUSW 의 경우는?
위 규칙대로 해석한다면 Unsigned Word 타입으로 unsiged short : 16 bit 이며 오버플로우시 + 부호를 유지한다로
볼 수 있다
배열에 값 담아 놓고 c++ 로 더할때와 simd 를 사용해서 더할때와의 속도차 비교
[소스코드 날림 주의.. ㅋ]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 | #include <iostream> #include <fstream> #include <windows.h> #include <string.h> #include <chrono> int totalSum(int size, int data[]) { int sum=0; for(int i=0;i< size; ++i) { sum += data[i]; } return sum; } int main() { const int unit = 16; const int size = 40002; int _package=4, totalByte =0; int data[size] = { 0, }; int result[4] = {0,}; int quotientByte = 0; int quotient = (size * _package) / unit; // 16 byte로 떨어지는 개수, 소수점 버림 int remainder = (size * _package) % unit; // 16 byte 이외의 엽ㄴ int total = 0; std::fill(data, &data[size], 2); std::chrono::system_clock::time_point start1 = std::chrono::system_clock::now(); std::cout<<"C++ total : "<<totalSum(size,data)<<std::endl; //80004 std::chrono::duration<double> sec1 = std::chrono::system_clock::now() - start1; std::cout << "simd 걸린 시간(초) : " << sec1.count() << " seconds" << std::endl; std::chrono::system_clock::time_point start = std::chrono::system_clock::now(); __asm { pushad mov eax, 16 mov ecx, quotient mul ecx mov quotientByte, eax lea esi, data pxor xmm1, xmm1 mov ecx, 0 loopAdd: movdqu xmm0, [esi + ecx] //16 byte 를 xmm0 에 복사 paddd xmm1, xmm0 add ecx, unit cmp ecx, quotientByte jl loopAdd //0이 아니면 movdqu result, xmm1 popad emms } //일단 지금까지의 합 구하기 (이 구문은 나중에 simd 로 한번에 처리할 수 있음) for (int i=0;i<_package;++i) { total += result[i]; } //나머지 여분 값 더하기 for(int i= quotientByte/_package; i< (quotientByte +remainder)/ _package; ++i) { total += data[i]; } std::chrono::duration<double> sec = std::chrono::system_clock::now() - start; std::cout << "simd 걸린 시간(초) : " << sec.count() << " seconds" << std::endl; std::cout << "SIMD total : " << total << std::endl; //80004 system("pause"); return 0; } | cs |
simd 연산으로 더한 결과가 훨씬 빠름을 알 수 있다
최종 total 값이 자료형의 범위를 넘지 않는다면 더 작은 바이트(4바이트가 아닌 2바이트)에서 연산 할 경우 더 높은 성능향상을
기대할 수 있다
'운영체제 & 병렬처리 > TBB & SIMD' 카테고리의 다른 글
EMMS 이 명령어가 필요한 이유 : clear floating-point stack (0) | 2018.02.13 |
---|---|
SIMD 로 배열 copy 작성__declspec(align(16)) 과 movdqu, movdqa (0) | 2018.02.13 |
simd 명령어의 의미 (p + operation + type) (0) | 2018.02.13 |
CPU 의 이해2 - E(A~D)X,...,XMM0~7,~15 (Register Bank) (0) | 2018.02.09 |
CPU 구조의 이해(명령어 처리의 이해) (0) | 2018.02.09 |