티스토리 뷰
안녕하세요. Teus입니다.
이번 포스팅은 SIMD(Single Instrunction Multi Data)를 다룹니다.
이번에는 AVX2의 기본 연산 중 쓸만한 함수 중 Permuting and Shuffling 을 다룹니다.
1. Permuting
Permuting은 사용자가 원하는 Order를 주고, 해당 Order를 기준으로 rearranged Vector를 구할 수 있는 방법입니다.
Data Type | Description |
---|---|
_mm/mm256_permute_ps/pd | Select elements from the input vector based on an 8-bit control value |
_mm256_permute4x64_pd/epi64 | Select 64-bit elements from the input vector based on an 8-bit control value |
_mm256_permute2f128_ps/pd/si256 | Select 128-bit chunks from two input vectors based on an 8-bit control value |
_mm/mm256_permutevar_ps/pd | Select elements from the input vector based on bits in an integer vector |
_mm256_permutevar8x32_ps/epi32 | Select 32-bit elements (floats and ints) using indices in an integer vector |
여기서 보면 8bit control value를 사용한다고 되어 있습니다.
아래 예시를 보실까요?
ret = _mm256_permute_ps(vec, 0b00110101)
8bit 의 2진수를 사용해서 4개를 선택하는 multiplex처럼 동작하게 만듭니다.
이때 128bit 단위로 Data가 selecting되는것을 볼 수가 있습니다.
근데 이때 또 ps와 pd가 다른 연산을 하게됩니다(하아 꿀밤마렵다😖)
ret = _mm256_permute_pd(vec, 0b0101)
_mm256_permute_pd
64bit 실수의 경우 4개의 2진수를 받고
128bit 중 상위 64bit을 가져갈지, 하위 64bit을 가져갈지 정하게 됩니다.
그래서 ps와 유사하게 현재 Vector를 2개로 쪼개고
그 반에서 원하는걸 골라가는것이 가능하지만
64bit을 사용할 경우 둘중 하나를 고르는 2지선다 밖에 불가능 하게 됩니다.
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <xmmintrin.h>
#include <immintrin.h >
int main() {
__m256d arr1 = _mm256_setr_pd(0.5, 0.9, 0.1, 0.4);
__m256d ret = _mm256_permute_pd(arr1, 0b0011);
double* my_ret = (double*)&ret;
double* _arr1 = (double*)&arr1;
for (int i = 0; i < 4; i++) {
printf("idx : %d, arr1[%d] = %f\n", i, i, _arr1[i], i);
}
for (int i = 0; i < 8; i++) {
printf("idx : %d, i : %f\n", i, my_ret[i]);
}
}
보는것처럼 처음 두개의 실수중 2번째, 다음 두 실수중 1번째를 설택하게 만들 수가 있습니다.
이 외에 다른 연산들을보면
_mm256_permute{var_count}*{bit_count}_ps/pd/epi
형태로 되어있습니다.
위 연산들은 주어진 Vector의 bit을 bit_count로 쪼갠다음, 그중 var_count만큼 선택할 수 있는 함수입니다.
_mm256_permute4x64_pd
를 예시로보면
8bit 2진수를 사용해서
4개의 64bit 실수를 multiplexing하는 연산인것을 볼 수가 있습니다.
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <xmmintrin.h>
#include <immintrin.h >
int main() {
__m256d arr1 = _mm256_setr_pd(0.5, 0.9, 0.1, 0.4);
__m256d ret = _mm256_permute4x64_pd(arr1, 0b00011011);
double* my_ret = (double*)&ret;
double* _arr1 = (double*)&arr1;
//float* _arr2 = (float*)&arr2;
for (int i = 0; i < 4; i++) {
printf("idx : %d, arr1[%d] = %f\n", i, i, _arr1[i], i);
}
for (int i = 0; i < 8; i++) {
printf("idx : %d, i : %f\n", i, my_ret[i]);
}
}
2. Shuffling
Shuffling은 2개의 Vector와 1개의 8bit 2진수를 사용해서
하나의 Rearranged Vector를 만드는 연산 입니다.
Data Type | Description |
---|---|
_mm256_shuffle_ps/pd | Select floating-point elements according to an 8-bit value |
_mm256_shuffle_epi8/32 | Select integer elements according to an 8-bit value |
_mm256_shufflelo/shufflehi_epi16 | Select 128-bit chunks from two input vectors based on an 8-bit control value |
_mm256_shuffle_pd
를 예로 들어보겠습니다.
_mm256_shuffle_pd
위처럼 동작하게 됩니다. 실제 코드를 봐도 아래처럼 결과가 나오게 됩니다.
이 연산들을 잘 사용하면, 두 Vector를 적당히 섞을수가 있습니다.
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <xmmintrin.h>
#include <immintrin.h >
int main() {
__m256d arr1 = _mm256_setr_pd(0.5, 0.9, 0.1, 0.4);
__m256d arr2 = _mm256_setr_pd(0.1, 0.3, 0.7, 0.4);
__m256d ret = _mm256_shuffle_pd(arr1, arr2, 0b0110);
double* my_ret = (double*)&ret;
double* _arr1 = (double*)&arr1;
double* _arr2 = (double*)&arr2;
for (int i = 0; i < 4; i++) {
printf("idx : %d, arr1[%d] = %f, arr2[%d] = %f\n", i, i, _arr1[i], i, _arr2[i], i);
}
for (int i = 0; i < 8; i++) {
printf("idx : %d, i : %f\n", i, my_ret[i]);
}
}
'C언어 잡기술 > SIMD(AVX)' 카테고리의 다른 글
AVX 튜토리얼6. 포인터 사용하기 (0) | 2024.04.24 |
---|---|
AVX 튜토리얼4. FMA연산 (0) | 2024.04.24 |
AVX 튜토리얼3. mul/divide연산 (0) | 2024.04.24 |
AVX 튜토리얼2. Add/Sub연산 (0) | 2024.04.24 |
AVX 튜토리얼1. DataType (0) | 2024.04.02 |
- Total
- Today
- Yesterday
- C++
- Python
- hash
- 사칙연산
- stack
- 컴퓨터그래픽스
- 자료구조
- Search알고리즘
- 알고리즘
- 완전탐색 알고리즘
- GDC
- AVX
- 코딩테스트
- 분할정복
- 동적계획법
- 이분탐색
- 프로그래머스
- 병렬처리
- prime number
- Sort알고리즘
- SIMD
- heap
- git
- Greedy알고리즘
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |