movdqu
mov : asm 에서의 mov 와 유사한 의미
dq : double quad (word) 로 quad word는 word 의 4배 인 8 byte 와
앞의 double 이 붙어 2*8 = 총 16 바이트인데 word 가 기본 pack 사이즈를 말함으로 2바이트씩 나눈 배열을 말함
u : unalign 으로 메모리에 있는 값들이 정렬되지 않은 값을 레지스터로 옮길때 붙이는 첨자
(정렬되지 않은것은 캐쉬미스가 발생하여 오래 걸릴수 있음, 하단 그림 참조)
movdqa
a : align : 메모리가 정렬된 상태로 정렬돈 메모리를 레지스터로 복사 시킬때에는 16개의 바이트의 메모리가 모두
붙어 있기 때문에 캐쉬에서 레지스터로 옮길때 부하없이 로드할 수 있다 (하단 그림 참조)
a를 제외한 나머지는 movdqu 에서 movdq 들과 동일한 의미
SIMD 로 배열 copy 작성
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 | int main(int argc, char* argv[]) { short A[8] = {1,2,3,4,5,6,7,8}; short B[8] = {0}; __asm { pushad movdqu xmm0, A //한 사이클에 모두 복사된다 movdqu B, xmm0 //한 사이클에 모두 복사된다 popad emms } printf("B : %d,%d,%d,%d,%d,%d,%d,%d\n",B[7],B[6],B[5],B[4], B[3],B[2],B[1],B[0]); return 0; } | cs |
배열에서 xmm0 레지스터로 copy 되는 내역을 볼 수 있는데 순서는 반대로 copy 된다
xmm0 에서 배열로 copy 될때도 반대로
그리하여 다시 배열로 올때는 일반적으로 예상할 수 있는 A 상태 그대로의 순서대로 오는 것을 알 수 있다
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | - xmm0 {m128_f32= {1.837e-40#DEN, 3.673e-40#DEN, 5.510e-40#DEN, 7.347e-40#DEN}
m128_f64= {5.562748306789e-309#DEN, ...} ...} __m128 + m128_f32 {1.837e-40#DEN, 3.673e-40#DEN, 5.510e-40#DEN, 7.347e-40#DEN} float[4] + m128_f64 {5.562748306789e-309#DEN, 1.112551783418e-308#DEN} double[2] + m128_i8 "\x1" char[16] - m128_i16 {1, 2, 3, 4, 5, 6, 7, 8} short[8] [0] 1 short [1] 2 short [2] 3 short [3] 4 short [4] 5 short [5] 6 short [6] 7 short [7] 8 short + m128_i32 {131073, 262147, 393221, 524295} int[4] + m128_i64 {1125912791875585, 2251829878849541} __int64[2] + m128_u8 "\x1" unsigned char[16] + m128_u16 {1, 2, 3, 4, 5, 6, 7, 8} unsigned short[8] + m128_u32 {131073, 262147, 393221, 524295} unsigned int[4] + m128_u64 {1125912791875585, 2251829878849541} unsigned __int64[2] eax 39226256 unsigned int | cs |
XMM0 = 0008000700060005-0004000300020001
XMM1 = 0000000000000000-0000000000000000
XMM2 = 0000000000000000-0000000000000000
XMM3 = 0000000000000000-0000000000000000
XMM4 = 0000000000000000-0000000000000000
XMM5 = 0000000000000000-0000000000000000
XMM6 = 0000000000000000-0000000000000000
XMM7 = 0000000000000000-0000000000000000
결과
B : 8,7,6,5,4,3,2,1
[movdqa]
정렬된 데이이터의 데이터 복사
__declspec(align(16)) 과 movdqa를 사용한 예이며 결과는 movdqu 와 동일하다
단 주의해야하는 점은 movdqa 의 경우 정렬된 데이터를 취급함으로 __declspec(align(16)) 를 배열에서 빼고
실행할 경우 크래쉬가 발생한다
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | int main(int argc, char* argv[]) { __declspec(align(16)) short A[8] = {1,2,3,4,5,6,7,8}; __declspec(align(16)) short B[8] = {0}; __asm { pushad movdqa xmm0, A movdqa B, xmm0 popad emms } printf("B : %d,%d,%d,%d,%d,%d,%d,%d\n",B[7],B[6],B[5],B[4], B[3],B[2],B[1],B[0]); return 0; } | cs |
반응형
'운영체제 & 병렬처리 > TBB & SIMD' 카테고리의 다른 글
SIMD 연산(PADD) 를 이용한 총 합 구하기 (0) | 2018.02.19 |
---|---|
EMMS 이 명령어가 필요한 이유 : clear floating-point stack (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 |