고급 벡터 확장

 

Advanced Vector eXtensions.
1. 개요
2. 특징
2.1. AVX
2.2. AVX2
2.3. AVX-512
2.3.1. 프로파일
2.3.1.1. F, CD, ER, PF
2.3.1.2. VL, DQ, BW
2.3.1.3. IFMA52, 4FMAPS, VBMI, VBMI2
2.3.1.4. VPOPCNTDQ
2.3.1.5. VNNI, 4VNNIW
2.3.1.6. BF16
2.3.1.7. BITALG
2.3.1.8. VP2INTERSECT
3. 지원 프로세서
3.1. AVX
3.2. AVX2
3.3. AVX-512
4. 관련 항목


1. 개요


[image]
2008년 4월 인텔 개발자 포럼에서 발표된 x86 SIMD 명령어 세트로 SSE 명령어 세트 시리즈의 후속작이다.
2011년에 출시한 인텔 샌디브릿지 마이크로아키텍처에서 최초로 지원한다.

2. 특징


[image]
MMX에서 SSE로 넘어가던 시기에서 최대 4배에 이르는 성능 향상폭을 기록했던 것 처럼, AVX의 지원은 최대 2.5배, AVX-512에서는 7배가 넘는 큰 성능 향상폭을 기록한다.
성능 향상에 대한 상세 설명
샌디브릿지가 엄청난 인기를 끌 수 있었던 비결 중의 하나이기도 하다.
반면에 펜티엄, 셀러론 시리즈에서는 보통 지원하지 않으며, 샌디브릿지 세대에 들어서야 SSE4.x를 지원하게 되었다.
전통적으로 인텔AMD보다 빠르게 적용중이다.
이 명령어를 활성화하면[1] 엄청난 부하가 걸려 어마어마한 발열을 볼 수 있다. 하지만 무턱대고 꺼버리면, 해당 명령어를 지원하는 SW[2]에서 성능이 몇% 수준이 아니라 수배나 떨어지기 때문에, 성능을 위해 오버클럭하는 사람들은 함부로 못 끈다. 하지만 성능이 아니라 단순히 높은 클럭만을 위하는 변태 오버클럭커들은 반드시 끄는 명령셋 중 하나이다.[3]
성능 향상이 커 페도라(운영 체제) 32 부터는 필수 옵션이라 일반 사용자는 성능을 떠나서 함부로 끄면 안된다. 부팅이 안될 수 도 있다.

2.1. AVX


SIMD 레지스터 폭이 128비트에서 256비트로 증가되었고, 2 피연산자 구조에서 3 피연산자 구조로 변경[4]되었다. 다만 3 피연산자 연산은 SIMD 명령어에 한정되고, EAX와 같은 범용 레지스터를 지원하지 않는다. 또 SIMD 메모리 피연산자의 정렬 요구도 완화되었으며 새롭게 VEX 코딩 방식이 도입되어 레거시 SSE와 AVX코드를 함께 사용하여도 속도 저하를 피할 수 있다.
이 VEX 코드가 적용된 어셈블리 명령은 앞에
v
를 붙이게 되고 Mutation하는 레지스터에 따라 AVX-128, AVX-256 등으로 나뉘며 예를 들어 XMM만을 지원하는
movdqa
vmovdqa
가 되고 VEX 버전의 경우 XMM과 YMM을 모두 사용할 수 있고 속도 저하도 일어나지 않기 때문에 SSE 코드를 그대로 컴파일만 다시 하면 속도 저하 페널티가 없다는 장점이 있다.
참고로 AVX는 GCC 4.6, 인텔 컴파일러 11.1, Open64 컴파일러 4.5.1, Free Pascal 컴파일러 2.7.1부터 지원하며, 운영체제는 Windows 7 SP1, 리눅스 커널 2.6.30 이상부터 지원한다.

2.2. AVX2


인텔 하스웰 마이크로아키텍처에서 최초로 지원한다.
대부분의 벡터 정수 SSE와 256비트 AVX 명령어가 확장되었고, AVX에서 지원하지 않았던 범용 레지스터에서의 3 피연산자 덧셈/곱셈 연산을 지원하며, FMA3과도 호환된다. 또한 벡터 주소 방식을 지원하고, 벡터 요소의 비 연속 메모리 위치의 로드를 지원하며 벡터 시프트도 가능하게 되었다.

2.3. AVX-512


2016년 제온 파이 x200 시리즈(Knights Landing)에서 먼저 도입되었으며, 서버용 CPU는 2017년 제온 스케일러블 시리즈에 사용된 스카이레이크-SP, 데스크탑 CPU 중에선 2017년 인텔 코어 X 시리즈에 사용된 스카이레이크-X에서 최초로 지원한다. 요약하자면 256-bit 단위이던 AVX2가 512-bit로 확장된 명령어 세트이다. 기존 AVX와 달리 프로세서별로 지원 명령어가 파편화되어 있다(...) 어느 쪽이든 AVX-512F와 AVX-512CD는 기본적으로 지원하나 그 이상부턴 HEDT/제온 기반 CPU인가 제온 Phi 기반 CPU인가에 따라서 확연하게 갈리게 된다.
Prime95 개발진인 GIMPS 측에 따르면 AVX-512 지원의 경우 이를 제대로 사용하려면 DDR4 규격 기준으로 쿼드 채널 메모리가 필요하다고 한다. 구조적으로 메모리 4개가 필요한 것은 아니지만, 현 세대 메모리들이 512-bit나 되는 거대한 레지스터 폭을 가진 연산을 뒷받침하려면 쿼드 채널 상당의 메모리 대역폭 정도는 되어야 하기 때문.[5] 이러다보니 AVX-512로 얻을 수 있는 이득을 제대로 뽑아 먹을 수 있는 상용 프로그램은 거의 없다고 봐도 된다. 초기에는 Trial factoring에 한해서만 제한적으로 사용되었지만, 2019년 4월 23일에 발표된 29.8 버전부터 정식으로 사용 가능해졌다. 린팩도 AVX-512 자체는 몇 년 전부터 지원해왔지만 제대로 지원하는 건 극히 최근의 일이기 때문.
256-bit 폭을 지닌 기존의 AVX도 처음 등장할 당시에는 구세대 SSE 계열이나 MMX에 비해 엄청난 발열과 부하로 인해 많은 오버클러커들을 좌절시켰지만, AVX-512는 그보다 더더욱 심각한 수준이라 FM 수준의 오버클럭 안정화를 고수하던 매니아 유저들마저도 회의적으로 만들 정도로 심각한 부하를 자랑한다. Windows의 작업 관리자나 모니터링 프로그램에서 CPU 이용률이 100%로 같더라도 실제 소비전력과 온도 및 발열량에서 차이가 나타날만큼 현존 최고의 부하 강도를 지니는 명령어 셋이라고 봐도 과언이 아니다! 물론 그에 비례해서 성능도 크게 오르지만, 어디까지나 제대로 지원이 된다는 전제 하에서나 그런 것이니.
이러한 문제 때문에 일부 컴파일러는 프로그래머가 직접 어셈블리나 인트린식으로 AVX512 명령을 사용하거나 수동으로 옵션을 주지 않는 이상 Auto Vectoriziation에 AVX-512의 ZMM을 사용하지 않고 AVX의 YMM 을 사용하도록 제한을 걸어뒀다.
파편화 문제로 리누스 토발즈에게 욕을 얻어먹었다.# 차라리 AVX에 할당할 트랜지스터를 모아서 AMD처럼 코어 수나 늘리라고 했다.
SSE 최적화를 제대로 해 본 사람이라면 알겠지만, SSE 도 SSE, SSE2, SSE3, Supplement SSE3, SSE4.1, SSE4.2 이렇게 조금씩 조금씩 명령어를 추가했기 때문에, 다양한 플랫폼에 동작하는 SSE 최적화 구현을 만들려면 예를 들어 up-to-SSE2 구현, up-to-Supp.SSE3 구현, up-to-SSE4.2 구현 이렇게 여러 구현을 만들어두고, CPU 가 지원하는 명령어셋을 인식해서 그에 맞는 구현을 호출하도록 해야했다. 아니면 최신 명령어셋이 주는 이점을 포기하는 대신 가장 널리 지원되는 쪽에 초점을 맞추어 up-to-SSE2 혹은 up-to-Supp.SSE3 구현 하나만 만들던가. 물론 시간이 한참 흐른 요즘에야 저전력 Intel N 시리즈 CPU 도 SSE4.2 까지 다 지원하니까 번거로움이 많이 사라졌지만, ARM NEON 이 그냥 ARM NEON 명령어 셋 하나로 끝나는 것에 비하면 Intel SSE 최적화는 엄청나게 번거로워 프로그래머의 원성을 살 수 밖에 없었다.[6][7] 따라서 SSE 다음으로 도입한 AVX 에서도 명령어셋을 AVX, AVX2 로 쪼개놓은 것을 두고 아직 Intel 은 정신 못차렸다고 욕먹을 만 한데, 한 술 더 떠 AVX512 에서는 명령어셋을 여러 개로 쪼개놓은 것도 모자라 최신 CPU 가 더 많은 명령어셋을 포괄적으로 지원하는 것도 아니고 라인업 별로 각각 다른 셋을 지원하게 만들어놨으니 엄청난 욕을 처먹는 수 밖에.
아래의 AVX-512 프로파일 문단에서 확인 할 수 있듯이, AVX에서 가능한 벡터 연산들은 AVX-512에서 추가된 기능들도 있긴 하지만 F, CD, ER, PF로 죄다 쪼개뒀다.
막말로 GPU 뺨칠 정도의 미친 성능 향상이 있다면 프로그래머를 갈아넣어서라도 AVX512 최적화 구현을 하거나 컴파일러를 고도화해서 자동으로 AVX512 코드를 생성하겠지만, AVX 대비 벡터 길이가 고작 2 배 늘어난 것에 불과하지 않는가? 따라서 아무도 사용하지 않을, 단지 Intel 의 마케팅 용 기술로 전락한 AVX512 에 투자할 트랜지스터가 있으면 다른데 투자하라는 일침이 나오는 것이다.[8]

2.3.1. 프로파일



2.3.1.1. F, CD, ER, PF

SSE, AVX의 512비트 버전이자 제온 파이 나이츠 랜딩과 Skylake-EP에서 지원한다.
각각 Foundation, Conflict Detection, Exponential-Reciprocal & Prefetch 의 약어로 AVX-512가 처음 등장하고 가장 먼저 도입된 프로파일이다.

2.3.1.2. VL, DQ, BW

각각 Vector Length, Doubleword-Quadword & Byte-Word 의 약어로 정수 관련 연산들과 8비트 부터 64비트 단위의 정수 관련 연산들이 추가되어 MMX, SSE2, AVX2의 연산을 모두 커버한다.
Skylake-X와 Cannon Lake 이후부터 지원한다.

2.3.1.3. IFMA52, 4FMAPS, VBMI, VBMI2

Integer Fused Multiply Add와 Vector Byte Manipulation Instruction 의 약자로 기존 FMA의 512비트 버전이다.
다만 IFMA52의 경우 52비트의 3항 연산이 지원되고, 4FMAPS의 경우 4항 연산을 지원한다.

2.3.1.4. VPOPCNTDQ

비트의 수를 세는 POPCNT 명령어와 동일하나 512비트에서 32비트 또는 64비트 단위로 마스크 입혀서 한 명령어로 처리가 가능하다.

2.3.1.5. VNNI, 4VNNIW

Vector Neural Network Instruction의 약자.
8비트 또는 16비트 단위의 페어를 연산하고 4VNNIW의 경우 4개의 블럭을 한번에 처리할 수 있다.
이름에서 알 수 있듯이 머신러닝에서 사용되는 인공 신경망 가속을 위한 기능이고 AVX2의 epi8단위 연산을 사용해서 구현하는 것 보다 VNNI를 사용하면 스루풋이 훨씬 증가하긴 하지만 VNNI를 지원하는 최고 성능의 CPU를 2소켓으로 구현해도 한개의 GPGPU처리보다 느리다는것이 함정.

2.3.1.6. BF16

Bfloat16, 또는 Brain Float Point 16 를 처리하는 명령어 세트.
스칼라곱 연산을 지원하고 VNNI와 함께 쓰이며 bfloat16 연산을 위해 32비트 부동소숫점을 16비트 부동소수점으로 라운딩 하는 보조적인 기능도 있다.

2.3.1.7. BITALG

Bit Algorithm 의 약자.
8비트 또는 16비트의 세트의 POPCNT 계산이나 비트 단위의 셔플링을 지원한다.

2.3.1.8. VP2INTERSECT

Vector Pair Intersection의 약자
두 벡터간 교집합을 연산하기 위해 사용되며, 만약 두 레지스터간 중복되는 원소들이 있으면 해당되는 비트마스크를 리턴한다.
다만 원소는 32비트 또는 64비트 정수로 제한된다.

3. 지원 프로세서



3.1. AVX


인텔
AMD

3.2. AVX2


인텔
AMD

3.3. AVX-512


인텔

4. 관련 항목



[1] 프라임 95, 링스[2] 게임, 인코딩, 시뮬레이션 등 CPU에 부하가 큰 SW들[3] 이들은 성능이 아니라 고클럭만 요구하기 때문에 CPU에 수율 좋은 코어 1개만 살리고 모조리 꺼버리고 쿨링을 위해 액체 헬륨을 붓는 이들이라 AVX 같은건 장애물로 여긴다.[4] 기존의 SSE에서는 최대 'A=A+B' 연산밖에 불가능하지만, AVX에서는 'A=B+C'가 가능하다. 별 것 아닌 것 같아보이겠지만, A = 10 + 5라는 연산을 SSE에서는 A = 10을 먼저 수행하고 그 다음에 A = A+ 5로 총 2회의 연산이 들어가며, AVX에서는 A = 10 + 5로 한번에 연산할 수 있다는 것이다. 상당히 큰 영향이 있을 수밖에 없다.[5] 가령 메모리에서 값을 읽어오는데 1 사이클이 필요하다고 했을 때 2021년 개인용 컴퓨터에서 많이 사용되는 128비트의 메모리 대역폭으로는 한 레지스터를 모두 채우는데만 4사이클이 필요하게 된다. 물론 실제 프로그램들이 달랑 한 레지스터만 읽어오는게 아니라 여러 값들을 메모리에서 읽어오게 되기 때문에 메모리 대역폭이 실행 속도에 상당히 큰 영향을 주게 된다.[6] 단 이건 그냥 ARM 이 훨씬 짧은 역사를 가졌고 저전력을 추구하는 프로세서였기 때문에(지금은 아니다) 그런거지 ARM 이 특별히 무언가를 잘 한건 아니다. ARM 도 시간이 지나면 결국 파편화가 되던지 하위 호환을 포기하던지 아예 고성능 벡터 명령어셋을 더 추가하지 않던지 그런 방법밖에 없다. 물론 뒤에도 써있지만 애초에 AVX-512 가 까이는 건 단지 파편화때문이 아니다.[7] ARM 도 VFP 라고 현재 사실상 사장된 벡터 명령어셋이 있다. VFP 는 명령어 하나로 여러개의 floating point register 여러개를 벡터처럼 묶어서 동시처리하는 것. 하지만 32b floating point register 숫자 자체에 빡빡한 한계가 있기 때문에 제대로 활용하기도 힘들도 성능 향상도 한계가 있다. 즉 ARM 도 뻘짓하다가 뻘짓을 깨닫고 VFP 를 사장시키고 단일화된 128b NEON 을 내놓았고 지금 굳이 억지로 인텔을 쫓아가겠다고 SSE1/2 나 AVX1/2 에서 했던 식으로 정수 벡터 연산과 실수 벡터 연산을 분리해서 256b 벡터 명령어셋을 추가하고 있지도 않고 있다. 그에 비하면 인텔은 SSE 에서 지속적인 뻘짓을 해놓고도 이를 AVX 에서도 이어갔으며 AVX512 에서는 오히려 뻘짓을 극대화시켰다는게 문제다. 이것은 단순히 ARM 보다 역사가 길어서 어쩔 수 없다던가 혹은 파편화는 결국 불가피하다는 논리로 쉴드쳐줄 수 있는 부분이 아니다. 리누스 토발즈가 AVX512 를 깐게 AVX512 때문에 발열 많아져서 오버클럭 안되는 것 때문에 그런 것 같은가?[8] 다만 최근 11세대 코브 시리즈의 유출 내용에 따르면 AVX512와 기존 10세대 프로세서간 성능 격차는 22퍼센트 정도이나 이 성능 향상이 결코 많은게 아니다. C/C++ 코드에 SSE 만 적용해도 최소 2~3 배, 8 bit 처리일 경우 10 배 이상 빨라지는게 보통이고, 본격적으로 GPU 를 쓰면 성능 향상이 못해도 수십배에서 수백배까지 나는게 보통이다. 괜히 요즘 엄청난 연산량을 요하는 딥러닝 트레이닝이 GPU 를 기본으로 쓰는게 아니다. (그것도 테슬라급 이상 GPU 를 PC 하나에 4 개 이상씩 꽂아서 쓴다.) 22 퍼센트 정도는 memory access pattern (cache fit) 조정 등 C/C++ 코드 자체의 최적화만 잘해도 나오는 경우가 많은 정도에 불과하고, 따라서 고작 22 퍼센트 때문에 파편화된 AVX512 에 목맬 사람은 아무도 없다.