벡터 프로세서

Vector processor

컴퓨팅에서 벡터 프로세서 또는 어레이 프로세서는 중앙 처리 장치(CPU)로, 벡터라고 불리는 대규모 1차원 데이터 어레이에서 효율적이고 효과적으로 동작하도록 설계된 명령 세트를 구현합니다.이는 명령어가 단일 데이터 항목에서만 작동하는 스칼라 프로세서와 대조적이며, 동일한 스칼라 프로세서의 일부에는 추가 단일 명령어, 다중 데이터(SIMD) 또는 SWAR 연산 장치가 있습니다.벡터 프로세서는 특정 워크로드, 특히 수치 시뮬레이션 및 유사한 작업의 성능을 크게 향상시킬 수 있습니다.벡터 처리 기술은 비디오 게임 콘솔 하드웨어 및 그래픽 액셀러레이터에서도 작동합니다.

벡터 머신은 1970년대 초에 등장하여 1970년대부터 1990년대까지 슈퍼컴퓨터 설계, 특히 다양한 Cray 플랫폼을 지배했습니다.기존 마이크로프로세서 설계의 가격 대비 성능 비율이 급격히 떨어지면서 1990년대 벡터 슈퍼컴퓨터의 성능이 저하되었습니다.

역사

초기 작업

벡터 프로세싱 개발은 1960년대 초 웨스팅하우스에서 솔로몬 프로젝트를 통해 시작되었습니다.솔로몬의 목표는 단일 마스터 CPU의 제어 하에 다수의 단순한 수학 공동 프로세서를 사용함으로써 수학 성능을 획기적으로 향상시키는 것이었습니다.CPU는 모든 산술논리유닛(ALU)에 대해 1개의 공통 명령어를 사이클당 1개씩 공급했지만 각 명령어마다 데이터 포인트가 다릅니다.이를 통해 Solomon 머신은 어레이 형태로 공급되는 대규모 데이터 세트에 단일 알고리즘을 적용할 수 있었습니다.

1962년 웨스팅하우스는 이 프로젝트를 취소했지만 일리노이 대학에서 ILLIAC IV로 다시 시작했다.설계 버전은 원래 256개의 ALU를 갖춘 1개의 GFLOPS 머신을 필요로 했지만 1972년에 최종적으로 납품되었을 때 ALU는 64개뿐이었고 100~150개의 MFLOPS밖에 도달하지 못했습니다.그럼에도 불구하고, 기본적인 개념은 소리였으며, 계산 유체 역학 같은 데이터 집약적인 애플리케이션에 사용했을 때, ILIAC는 세계에서 가장 빠른 기계였습니다.각 데이터 요소에 대해 개별 ALU를 사용하는 ILIAC 접근 방식은 이후 설계에서는 일반적이지 않으며 종종 개별 범주인 대규모 병렬 컴퓨팅으로 언급됩니다.이 시기에 Flynn은 이러한 유형의 처리를 SIMT의 초기 형태로 분류했습니다.

1967년 [1]Kartsev에 의해 기능이 있는 작업을 위한 컴퓨터가 제공되고 개발되었습니다.

슈퍼컴퓨터

최초의 벡터 슈퍼컴퓨터는 Control Data Corporation STAR-100과 Texas Instruments Advanced Scientific Computer(ASC)로, 각각 1974년과 1972년에 도입되었습니다.

기본 ASC(즉, "1개의 파이프") ALU는 스칼라와 벡터 계산을 모두 지원하는 파이프라인 아키텍처를 사용했으며, 피크 성능은 긴 벡터를 처리할 때 약 20 MFLOPS에 도달했습니다.확장 ALU 구성은 "2개의 파이프" 또는 "4개의 파이프"를 지원하여 2배 또는 4배의 성능 향상을 실현했습니다.메모리 대역폭은 이러한 확장 모드를 지원하기에 충분했습니다.

STAR-100은 CDC 7600과 같은 CDC 자체 슈퍼컴퓨터보다 속도가 느리지만 데이터 관련 태스크에서는 훨씬 작고 저렴한 가격에 대응할 수 있었습니다.그러나 이 기계는 벡터 명령어를 디코딩하고 프로세스를 실행할 준비를 하는 데 상당한 시간이 걸리기 때문에 실제로 속도를 높이려면 매우 구체적인 데이터 세트가 필요했습니다.

벡터 기술은 1976년 유명한 Cray-1에 의해 완전히 이용되었다.STAR-100이나 ASC와 같은 메모리에 데이터를 남기는 대신, 크레이 설계에는 각각 64개의 64비트 워드를 포함하는 8개의 벡터 레지스터가 있었다.벡터 명령은 레지스터 간에 적용되어 메인 메모리와 통화하는 것보다 훨씬 빠릅니다.STAR-100은 메모리 내의 긴 벡터에 대해 단일 연산을 적용하고 다음 연산으로 넘어가는 반면, Cray 설계는 벡터의 작은 부분을 레지스터에 로드하여 가능한 한 많은 연산을 데이터에 적용함으로써 훨씬 느린 메모리 액세스 연산을 피할 수 있습니다.

Cray 설계에서는 복수의 ALU가 아닌 벡터 명령을 구현하기 위해 파이프라인 병렬화를 사용했습니다.또한, 설계에는 서로 다른 명령에 대한 완전히 다른 파이프라인이 있었습니다. 예를 들어, 덧셈/감산은 곱셈이 아닌 다른 하드웨어에서 구현되었습니다.이를 통해 벡터 명령의 배지를 각 ALU 서브유닛에 파이프라인으로 연결할 수 있었습니다.이것은 벡터 체인이라고 불리는 기술입니다.Cray-1은 보통 약 80MFLOPS의 성능을 발휘했지만, 최대 3개의 체인을 가동하면 최대 240MFLOPS로 피크에 이를 수 있으며, 평균 약 150대로 당시의 어떤 기계보다 훨씬 빠릅니다.

4개의 스칼라/벡터 프로세서를 탑재한 Cray J90 프로세서 모듈

다른 예도 뒤따랐다.Control Data CorporationETA-10 머신을 통해 하이엔드 시장에 재진입하려 했지만 판매가 저조했고, 이를 슈퍼컴퓨팅 분야에서 완전히 퇴출할 기회로 삼았습니다.1980년대 초중반 일본 기업(후지쓰, 히타치, 일본전기공사(NEC))은 Cray-1과 유사한 레지스터 기반 벡터 머신을 선보였는데, 일반적으로 약간 더 빠르고 훨씬 더 작습니다.오리건주거점을 둔 부동 소수점 시스템(FPS)은 미니 컴퓨터용 애드온 어레이 프로세서를 구축하여 나중에 미니 컴퓨터 전용으로 개발하였습니다.

Cray는 Cray-2, Cray X-MP 및 Cray Y-MP를 탄생시킨 일련의 기계로 계속 퍼포먼스 리더를 유지하고 있습니다.이후 슈퍼컴퓨터 시장은 벡터 프로세서의 뛰어난 구현보다는 대규모 병렬 처리에 초점을 맞추고 있습니다.그러나 벡터 프로세싱의 이점을 인식하여 IBM은 벡터 프로세서 역할을 하기 위해 여러 스칼라 프로세서를 결합하는 슈퍼컴퓨터에 사용할 가상 벡터 아키텍처를 개발했습니다.

Cray-1과 유사한 벡터 슈퍼컴퓨터는 요즘 인기가 떨어지지만 NEC는 SX 시리즈 컴퓨터로 이러한 종류의 컴퓨터를 계속 만들어 왔다.최근 SX-Aurora TSUBASA는 물리적으로 그래픽 코프로세서와 유사한 카드 내의 HBM 2 모듈에 프로세서와 24GB 또는 48GB 메모리를 탑재하고 있지만 보조 프로세서로 기능하는 것이 아니라 PC 호환 컴퓨터를 탑재한 메인 컴퓨터입니다.

GPU

최신 그래픽 처리 장치(GPU)에는 컴퓨팅 커널에 의해 구동되는 셰이더 파이프라인 배열이 포함되어 있어 벡터 프로세서로 간주할 수 있습니다(메모리 레이텐시를 숨기기 위한 유사한 전략을 사용).Flynn의 1972년 논문에서 알 수 있듯이 SIMT 기반 GPU의 주요 구별 요소는 단일 명령 디코더-브로드캐스트를 가지고 있지만 동일한 명령을 수신하고 실행하는 코어가 그 외에는 상당히 정상적이라는 것입니다. 즉, 자체 ALU, 자체 레지스터 파일, 자체 로드/스토어 장치 및 자체 독립 L1 데이터 캐시입니다.따라서 모든 코어가 동시에 동일한 명령을 서로 잠금 스텝으로 실행하지만 완전히 다른 메모리 위치에서 완전히 다른 데이터를 사용하여 실행됩니다.이는 병렬 파이프라인 산술 연산의 실행으로만 엄격하게 제한되는 "충전된 SIMD"보다 훨씬 복잡하고 복잡합니다.오늘날 상용 GPU의 정확한 내부 세부 사항은 독점적인 비밀이지만, MIAOW[2] 팀은 AMDGPU [3]아키텍처의 서브셋을 구현하기에 충분한 일화 정보를 종합할 수 있었습니다.

현대 건축과의 비교

2016년 현재 대부분의 상용 CPU는 고정 길이 SIMD 명령을 사용하는 아키텍처를 구현하고 있습니다.첫 번째 검사에서는 여러 데이터 세트(벡터화, 명시적 길이)에서 동작하며 벡터 프로세서에서 기능을 차용하기 때문에 벡터 처리의 한 형태로 간주할 수 있습니다.그러나 정의상 SIMD의 추가만으로는 프로세서가 실제 벡터 프로세서로 인정될 수 없습니다.SIMD는 고정 길이이고 벡터는 가변적이기 때문입니다.이 차이는 다음 세 가지 카테고리를 보여주고 비교하는 예시와 함께 설명됩니다.Pure SIMD, Predicated SIMD 및 Pure Vector Processing.[citation needed]

그 외의 CPU 설계에는, 복수의 (벡터화된) 데이터 세트에서의 벡터 처리를 위한 복수의 명령이 포함되어 있습니다.일반적으로 MIMD(Multiple Instruction, Multiple Data)라고 불리며, VLIW(Very Long Instruction Word)로 실현됩니다.Fujitsu FR-V VLIW/벡터 프로세서는 두 가지 기술을 결합합니다.

SIMD와 벡터 프로세서의 차이점

SIMD 명령어 세트는 벡터 프로세서 명령어 세트와 비교했을 때 중요한 기능이 없습니다.이들 중 가장 중요한 것은 벡터 프로세서가 본질적으로 정의와 설계에 의해 시작되었을 때부터 항상 가변 길이였다는 것입니다.

순수(고정폭, 예측 없음) SIMD가 이력 ISA와 현대 ISA의 면밀한 분석과 비교를 통해 일반적으로 "벡터"라고 잘못 주장되는 경우, 실제 벡터 프로세서는 SIMD ISA에 [citation needed]없는 다음과 같은 특징을 가지고 있는 것으로 관찰될 수 있습니다.

  • 벡터 길이를 설정하는 방법(예:setvlRISCV RVV[5])의 지시 또는 제공REP반복을 2의 거듭제곱으로 제한하지 않고 어떤 형태로든 (명령 반복) 기능
  • 벡터 내의 요소에 대한 반복 및 감소.버전 0.10의 RISC-V 벡터에는 리덕션만 있으며 SX-Aurora 및 이후 Cray 시스템에는 리덕션과 [6][7][8]리덕션이 있습니다.

현재 ARM SVE2 [9]AVX-512에서 제공되는 모든 벡터 명령에 대한 포괄적인 개별 요소 수준 술어 마스크인 사전 SIMD(Flynn 분류법의 일부)는 벡터 프로세서로 거의 적합합니다.사전 정의된 SIMD는 고정 폭의 SIMD ALU를 사용하지만 가변 길이 벡터의 외관을 제공하기 위해 장치의 로컬 제어(사전 복제) 액티베이션이 가능합니다.아래의 예는 이러한 범주형 차이를 설명하는 데 도움이 됩니다.

SIMD는 고정폭 배치 처리이기 때문에 반복 및 축소에 대응할 수 없습니다.이것은, 이하와 같은 예에서 자세하게 설명되고 있습니다.

Simd vs vector.png

또한 벡터 [11]체인을 통해 벡터 프로세서는 SIMD보다 리소스 효율(하드웨어 사용 속도가 느리고 전력 절약은 가능하지만 [10]throughput 달성)이 향상될 수 있습니다.

LOAD, ADD, Multiply 및 STORE 시퀀스를 수행하는 4개의 64비트 요소에서 작동하는 SIMD 프로세서와 벡터 프로세서를 모두 고려합니다.SIMD 폭이 4인 경우 SIMD 프로세서는 ADD로 이동하기 전에 4개의 요소를 모두 로드해야 하며, Multiply로 이동하기 전에 모든 ADD를 완료해야 하며, 마찬가지로 STORE를 시작하기 전에 Multiply를 완료해야 합니다.이것은 정의와 [12]설계에 의한 것입니다.

4폭의 64비트 LOAD와 64비트 STORE를 동시에 실행해야 하는 경우 하드웨어(256비트 데이터 경로에서 메모리로) 비용이 많이 듭니다.64비트 ALU(특히 MULIPE)가 4개 있는 것도 마찬가지입니다.이러한 고비용을 피하기 위해 SIMD 프로세서는 1와이드 64비트 LOAD, 1와이드 64비트 STORE 및 2와이드 64비트 ALU만을 탑재해야 합니다.다중 이슈 실행 모델을 가정한 다이어그램에서 보듯이, 그 결과 작업을 완료하는 데 시간이 더 오래 걸립니다.여러 문제를 해결할 수 없는 경우 LD가 첫 번째 ADD와 동시에 발행(시작)되지 않을 수 있기 때문에 작업이 더 오래 걸립니다.4 와이드 64비트 SIMD ALU만 있는 경우 완료 시간은 더욱 나빠집니다.4개의 LOAD가 모두 완료된 경우에만 SIMD 동작이 시작되고 모든 ALU 동작이 완료된 경우에만 STORE가 시작됩니다.

반면 벡터 프로세서는 싱글 이슈로 SIMD ALU를 사용하지 않더라도 1와이드 64비트 LOAD와 1와이드 64비트 STORE(및 Cray-1에서는 ADD와 동시에 MULTIP를 실행하는 기능)만 있으면 부하가 1와이드, 스토어가 1과이드인 SIMD 프로세서보다4개의 조작을 고속으로 실행할 수 있습니다.벡터 체인에 의한 이 보다 효율적인 자원 활용은 SIMD에 비해 중요한 장점과 차이점이다. SIMD는 설계 및 정의상 결과 [13]그룹 전체를 제외하고 체인을 수행할 수 없다.

묘사

일반적으로 CPU는 한 번에 한두 개의 데이터를 조작할 수 있습니다.예를 들어 대부분의 CPU에는 기본적으로 "A를 B에 추가하고 결과를 C에 넣는다"는 명령이 있습니다.A, B 및 C의 데이터는 적어도 이론적으로는 명령어에 직접 인코딩될 수 있습니다.그러나 효율적인 구현에서는 그렇게 간단한 경우가 거의 없습니다.데이터는 raw 형식으로 전송되는 경우는 거의 없으며, 대신 데이터를 보관하고 있는 메모리 위치에 주소를 전달함으로써 "지정"됩니다.이 주소를 디코딩하여 메모리에서 데이터를 꺼내는 데 시간이 걸리고, 이 기간 동안 CPU는 요청된 데이터가 표시될 때까지 대기하고 있었습니다.CPU 속도가 증가함에 따라 이 메모리 지연 시간이 성능에 큰 장애가 되었습니다. 메모리 벽을 참조하십시오.

이러한 단계에서 소비되는 시간을 줄이기 위해 대부분의 최신 CPU는 명령 파이프라인이라고 불리는 기술을 사용합니다.이 기술은 명령이 여러 서브유닛을 차례로 통과하는 것입니다.첫 번째 서브유닛은 주소를 읽어 디코딩하고, 다음 서브유닛은 해당 주소의 값을 "가져오기"하며, 다음 서브유닛은 연산 자체를 수행합니다.파이프라이닝의 경우 첫 번째 명령어가 CPU에서 나오기 전부터 다음 명령어의 디코딩을 시작하는 것이 포인트입니다(어드레스 디코더는 항상 사용됩니다).특정 명령의 완료에는 동일한 시간(지연 시간)이 소요되지만 CPU는 전체 작업을 한 번에 하나씩 처리하는 것보다 훨씬 빠르고 효율적으로 오버랩 방식으로 처리할 수 있습니다.

벡터 프로세서는 이 개념을 한 단계 더 발전시킵니다.명령만 파이프라인하는 것이 아니라 데이터 자체를 파이프라인으로 연결합니다.프로세서에는 A를 B에 추가하는 것뿐만 아니라 "여기서 여기까지"의 모든 숫자를 "여기서 저기까지"의 모든 숫자에 추가하라는 명령이 제공됩니다.명령어를 지속적으로 디코딩하고 그 명령어를 완료하기 위해 필요한 데이터를 가져오는 대신 프로세서는 메모리에서 단일 명령을 읽어내고 명령어 자체의 정의에 명령어가 마지막 주소보다 한 단계 더 큰 주소에서 다른 데이터 항목에서 다시 작동한다는 것을 암시합니다.이것에 의해, 디코딩 시간을 큰폭으로 절약할 수 있습니다.

이것이 어떤 차이를 가져올 수 있는지를 설명하기 위해 10개의 숫자로 이루어진 두 개의 그룹을 추가하는 간단한 작업을 고려합니다.일반적인 프로그래밍 언어에서는 숫자 쌍을 하나씩 차례로 집어서 추가하는 "루프"를 쓴다.CPU 에서는, 다음과 같이 됩니다.

가상 RISC 머신 ; a의 10개의 숫자를 b의 10개의 숫자에 추가하여 결과를 c에 저장합니다. ; a, b 및 c는 각각의 레지스터에 있는 메모리 위치라고 가정합니다.   움직이다  $10, 세어보세요   ; 카운트 : = 10 루프:   장전  r1, a   장전  r2, b   더하다   r3, r1, r2   ; r3 : = r1 + r2   가게 r3, c   더하다   a, a, $4     ; 앞으로 나아가다   더하다   b, b, $4   더하다   c, c, $4   데크   세어보세요        ;감소   동작하다  세어보세요, 고리  ; 카운트가 아직 0이 아니면 루프백합니다.   리트 

그러나 벡터 프로세서에 따르면 이 작업은 크게 다릅니다.

벡터 레지스터 v1-v3가 있다고 가정합니다. ; 사이즈가 10 이상인 경우   움직이다   $10, 세어보세요    ; 카운트 = 10   로드  v1, a, 세어보세요   로드  v2, b, 세어보세요   추가   v3, v1, v2   vstore v3, c, 세어보세요   리트 

명령어에는 루프가 전혀 없는 것에 주의해 주세요.이것은, 10개의 시퀀셜 조작을 실행한 하드웨어이기 때문입니다.실제로 루프 카운트는 명령 단위마다 명시적인 것입니다.

Cray 스타일의 벡터 ISA는 이를 한 걸음 더 나아가 벡터 길이(VL)라고 하는 글로벌 "카운트" 레지스터를 제공합니다.

다시 벡터 레지스터 v1-v3가 있다고 가정합니다. ; 사이즈가 10 이상인 경우   설정  $10        # 벡터 길이 설정 VL=10   로드   v1, a      # 로부터10개의 부하   로드   v2, b      # b로부터의 10 부하   추가   v3, v1, v2  # 10 추가   vstore v3, c       # 10개의 스토어를 c에 저장   리트 

[14]접근방식에는 몇 가지 절약이 있습니다.

  1. 3개의 주소 변환만 필요합니다.아키텍처에 따라서는 그 자체로 대폭적인 비용 절감을 실현할 수 있습니다.
  2. 또 다른 절약은 명령 자체를 가져와 디코딩하는 것입니다.이 작업은 10이 아닌 1회만 수행하면 됩니다.
  3. 코드 자체도 작기 때문에 메모리 사용 효율 향상, L1 명령 캐시 크기 감소, 소비 전력 감소로 이어집니다.
  4. 프로그램 크기가 축소됨에 따라 지점 예측이 더 쉬워졌습니다.
  5. 길이(SIMD 폭에 상당)가 명령어에 하드 코딩되지 않기 때문에 인코딩이 보다 콤팩트할 뿐만 아니라 "미래에도 견딜 수 있다"며 임베디드 프로세서 설계에서도 고성능을 추구하지 않고 벡터를 사용하여 다른 모든 이점을 얻을 수 있습니다.

게다가 최신의 벡터 프로세서 ISA에서는, 「Fail on First」또는 「Fault First」(아래를 참조)가 도입되어 한층 더 메리트가 있습니다.

그러나, 그 이상으로, 고성능 벡터 프로세서는, 복수의 기능 유닛이 이러한 수치를 병렬로 추가하는 경우가 있습니다.벡터 명령은 여러 개의 독립적인 연산을 지정하므로 이러한 숫자 간의 종속성 검사는 필요하지 않습니다.이것에 의해, 필요한 제어 로직이 심플화해, 스톨을 회피하는 것으로 퍼포먼스를 한층 향상시킬 수 있습니다.따라서 전체적으로 계산 작업이 훨씬 더 빠르게 완료되었으며, 제한 요인은 메모리에서 데이터를 가져오는 데 필요한 시간입니다.

이러한 종류의 해결책으로 모든 문제를 해결할 수 있는 것은 아닙니다.이러한 종류의 명령을 포함하면 코어 CPU가 복잡해집니다.이러한 복잡성으로 인해 일반적으로 다른 명령의 실행 속도가 느려집니다. 즉, 여러 개의 명령어가 연속적으로 추가되지 않을 마다 마찬가지입니다.명령어가 복잡해지면 디코더의 복잡성도 높아져 일반 추가와 같은 일반적인 명령어의 디코딩이 느려질 수 있습니다(이는 ISA 전체를 RISC로 유지함으로써 다소 완화될 수 있습니다.RVV는 고도의 기능에도 불구하고190개의 벡터 명령어를 추가합니다).[15]

벡터 프로세서는 전통적으로 대량의 데이터를 처리해야 할 경우에만 가장 잘 작동하도록 설계되었습니다.이러한 이유로 이러한 종류의 CPU는 주로 슈퍼컴퓨터에서 발견되었는데, 이는 슈퍼컴퓨터 자체가 일반적으로 일기예보센터나 물리연구소와 같은 엄청난 양의 데이터가 "파쇄"되는 곳에서 발견되었기 때문입니다.그러나 위와 같이 RISC-V RVV에 의해 입증되었듯이 벡터 ISA의 효율성은 임베디드 사용 사례에서도 매력적인 다른 이점을 가져옵니다.

벡터 명령

위의 벡터 의사 코드의 예에서는 벡터컴퓨터가 10개 이상의 번호를 1개의 배치로 처리할 수 있다는 큰 가정을 하고 있습니다.벡터 레지스터의 숫자가 많을수록 컴퓨터가 그렇게 큰 레지스터를 갖는 것은 불가능해진다.그 결과 벡터 프로세서는 루프 자체를 실행하는 능력을 얻거나 프로그래머에게 벡터 제어(상태) 레지스터를 공개합니다.일반적으로 벡터 길이라고 불립니다.

STAR-100과 같은 초기 벡터 컴퓨터에 있는 자기반복 명령어는 위의 조작이 하나의 명령으로 설명되어 있습니다.vadd c, a, b, $10)는 x86 아키텍처에도 탑재되어 있습니다.REP프레픽스그러나 하드웨어에서는 매우 간단한 계산만이 큰 비용 증가 없이 효과적으로 수행될 수 있습니다.STAR-100 아키텍처에서는 모든 오퍼랜드가 메모리에 있어야 하므로 액세스에 의한 지연도 커졌습니다.

하지만 흥미롭게도, Broadcom은 Videocore ISA의 모든 벡터 연산에 공간을 포함시켰습니다.REP그러나 반복에 메모리를 사용하는 STAR-100과는 달리 Videocore IV 반복은 산술 벡터 연산을 포함한 모든 연산에 있습니다.반복 길이는 2의 작은 전력 범위이거나 스칼라 레지스터 [16]중 하나에서 얻을 수 있습니다.

Cray-1은 프로세서 레지스터를 사용하여 벡터 데이터를 일괄 보관하는 아이디어를 도입했습니다.배치 길이(벡터 길이, VL)는 반복 길이가 명령 인코딩의 일부가 될 필요가 없다는 점에서 비디오코어 IV(그리고 결정적으로 아래에 보여질 SIMD)와 비교하여 동적으로 설정할 수 있다.이렇게 하면 각 배치에서 훨씬 더 많은 작업을 수행할 수 있습니다. 명령 인코딩도 훨씬 더 우아하고 콤팩트합니다.유일한 단점은 이 추가 배치 처리 용량을 최대한 활용하기 위해서는 메모리 부하와 저장 속도도 그에 따라 증가해야 한다는 것입니다.이것은 때때로[by whom?] Cray 스타일의 벡터 프로세서의 단점이라고 주장되기도 합니다.실제로는 GPU에서 볼 수 있듯이 하이 퍼포먼스 throughput을 실현하기 위한 일부입니다.이러한 문제는 GPU에서도 볼 수 있습니다.

현대의 SIMD 컴퓨터는 일반적인 스칼라 파이프라인만 사용하는 것에 비해 높은 수준의 병렬화를 위해 여러 개의 ALU를 직접 사용함으로써 초기 Cray를 개선한다고 주장한다.최신 벡터 프로세서(SX-Aurora TSUBASA 등)는 여러 내부 파이프라인 SIMD ALU에 여러 데이터를 발행함으로써 실행 시 벡터 프로그램에 의해 동적으로 선택된 번호를 조합합니다.마스크를 사용하여 데이터를 선택적으로 메모리 위치에 로드 및 저장하고 동일한 마스크를 사용하여 SIMD ALU의 처리 요소를 선택적으로 비활성화할 수 있습니다.SIMD를 탑재한 일부 프로세서(AVX-512, ARM SVE2)는 이러한 종류의 선택적 요소별("사전") 처리를 지원합니다.이러한 프로세서는 명명법상의 "벡터 프로세서" 또는 적어도 "벡터 프로세서"가 적합하다고 할 수 있습니다.요소별 예측(MMX, SSE, AltiVec)이 없는 SIMD 프로세서는 절대 그렇지 않습니다.

각각 독자적인 SIMD ALU를 갖춘 다수의 소형 컴퓨팅 유닛을 갖춘 최신 GPU에서는 SIMT(Single Instruction Multiple Threads)를 사용합니다.SIMT 유닛은 공유된 단일 브로드캐스트 동기 명령 유닛에서 실행됩니다."벡터 레지스터"는 매우 넓고 파이프라인이 긴 경향이 있습니다.SIMT의 "스레딩" 부분에는 각 컴퓨팅 유닛에서 독립적으로 데이터를 처리하는 방법이 포함됩니다.

또한 Broadcom Videocore IV와 같은 GPU 및 NEC SX-Aurora TSUBASA와 같은 기타 외부 벡터 프로세서는 너비가 의미하는 것보다 적은 벡터 단위를 사용할 수 있습니다. 즉, 64개의 번호 폭 레지스터에 64개의 유닛을 사용하는 대신 하드웨어는 하이브리드 접근에 16개의 유닛에 대해 파이프라인 루프를 실행할 수 있습니다.Broadcom Videocore IV는 이 하이브리드 어프로치에도 대응하고 있습니다.명목상으로는 SIMD QPU Engine은 명령에서 16길이의 FP 어레이 동작을 지원하며 실제로는 (다른) 스레드 형태로 [17]한 번에 4개씩 수행합니다.

벡터 명령 예시

이 예에서는 알고리즘("IAXPY")에서 시작하여 먼저 스칼라 명령으로 표시한 다음 SIMD, 사전 정의된 SIMD, 마지막으로 벡터 명령으로 표시합니다.이를 통해 기존의 벡터 프로세서와 현대의 SIMD 프로세서의 차이를 점차적으로 설명할 수 있습니다.이 예시는 32비트 정수 배리언트인 DAXPY 함수로 시작합니다(C:

무효 iaxpy(size_t n, 인트 a, 컨스턴트 인트 x[], 인트 y[]) {     위해서 (size_t i = 0; i < > n; i++)         y[i] = a * x[i] + y[i]; } 

각 반복에서 y의 모든 요소는 x의 요소에 a를 곱하여 여기에 추가됩니다.프로그램은 가독성을 위해 스칼라 선형 형태로 표현됩니다.

스칼라 어셈블러

이것의 스칼라 버전에서는 x와 y의 각 1개가 로드되어 1개의 계산이 처리되고 1개의 결과가 저장되며 루프가 발생합니다.

루프:   로드32  r1, x      ; 32비트 데이터 1개를 로드합니다.   로드32  r2, y   멀티32   r1, a, r1  ; r1 : = r1 * a   추가 32   r3, r1, r2 ; r3 : = r1 + r2   스토어32 r3, y   추가    x, x, $4   ; x : = x + 4   추가    y, y, $4   가라앉다    n, n, $1   ; n : = n - 1   jgz     n, 고리    ; n > 0인 경우 루프백합니다. 출력:   리트 

STAR와 같은 코드는 간결하지만 STAR-100의 벡터화는 메모리 액세스를 기반으로 설계되었기 때문에 정보를 처리하기 위해 추가 메모리 슬롯이 필요합니다.메모리 액세스가 추가로 필요하기 때문에 지연 시간이 2배 더 필요합니다.

  ; tmp가 사전 할당되어 있다고 가정합니다.   VMUL tmp, a, x, n ; tmp[i] = a * x[i]   추가 y, y, tmp, n ; y[i] = y[i] + tmp[i]   리트 

순수(미복제, 포장) SIMD

Flynn의 분류법에 기재된 여러 이름으로 알려진 현대식 SIMD 아키텍처는 대부분의 작업을 일괄적으로 수행할 수 있습니다.코드는 대부분 스칼라 버전과 비슷합니다.여기서 x와 y가 모두 올바르게 정렬되어 있다고 가정합니다(16의 배수에서만 시작).n은 4의 배수입니다.그렇지 않으면 마스크를 계산하거나 스칼라 버전을 실행하기 위해 몇 가지 셋업 코드가 필요하게 됩니다.또한 단순성을 위해 SIMD 명령에는 ARM NEON과 [18]같이 스칼라 피연산자를 자동으로 반복하는 옵션이 있다고 가정할 수 있습니다.그렇지 않은 경우 scalar 인수를 SIMD 레지스터 간에 복사하기 위해 "splat"(브로드캐스트)를 사용해야 합니다.

  스플래트 4   v4, a        ; v4 = a,a,a,a,a 

소요시간은 기본적으로 다음 벡터의 구현과 동일합니다.y = mx + c를 참조해 주세요.

vloop:   로드 32x4  v1, x   로드 32x4  v2, y   멀티32x4   v1, a, v1  ; v1 : = v1 * a   추가 32x4   v3, v1, v2 ; v3 : = v1 + v2   스토어 32x4 v3, y   추가      x, x, $16  ; x : = x + 16   추가      y, y, $16   가라앉다      n, n, $4   ; n : = n - 4   jgz       n, 루프   ; n > 0일 경우 되돌아가다 출력:   리트 

x 포인터와 y 포인터는 모두 16씩 증가합니다.이는 4개의 32비트 정수의 길이(바이트 단위)이기 때문입니다.알고리즘은 4폭 SIMD만 처리하도록 결정되었으며, 따라서 상수는 프로그램에 하드 코딩됩니다.

SIMD의 경우 단서는 위의 가정에 있었습니다. "n은 4의 배수"와 "aligned access"입니다. 이는 분명히 제한된 전문 사용 사례입니다.

현실적으로 n이 이 방법으로 제한될 수 없는 휴대용 라이브러리와 같은 범용 루프의 경우 SIMD 폭의 비배수에 대처하기 위한 SIMD 설정 및 청소의 오버헤드는 루프 자체의 명령 카운트를 훨씬 초과할 수 있습니다.하드웨어가 잘못 정렬된 SIMD 메모리액세스를 실행할 수 없는 최악의 경우 실제 알고리즘은 다음과 같습니다.

  • 먼저 SIMD 메모리 정렬 작업을 인계할 수 있는 첫 번째 지점까지 정렬되지 않은 데이터를 처리하는 준비 섹션을 준비해야 합니다.여기에는 스칼라 전용 조작(느림) 또는 소규모 패킹 SIMD 조작이 포함됩니다.각 복사본은 완전한 알고리즘 내부 루프를 구현합니다.
  • 마지막 몇 개의 요소(고정된 SIMD 폭에 맞지 않는 나머지 요소)까지 최대 SIMD 폭에서 정렬된 SIMD 루프를 수행합니다.
  • 청소 단계는 준비 섹션과 마찬가지로 크고 복잡합니다.

8폭 SIMD는 첫 번째 및 마지막 남은 SIMD 요소(0 <= n <= 7)를 커버하기 위해 먼저 4폭 SIMD 요소로 내부 루프 알고리즘을 반복하고, 그 다음에 2폭 SIMD, 그 다음에 1개(파형)로 테스트와 분기를 각각 사이에 두고 반복해야 한다.

이는 코드 크기를 3배 이상 증가시킵니다. 실제로 극단적인 경우 명령 수가 크게 증가합니다.이것은, AVX-512 의 iaxpy 의 예를 컴파일 해, 옵션을 사용해 간단하게 실증할 수 있습니다."-O3 -march=knl"gcc에 접속합니다.

시간이 지남에 따라 ISA 아키텍처는 성능을 지속적으로 향상시키도록 진화하면서 2와이드 SIMD, 4와이드 SIMD, 8와이드 이상의 SIMD를 추가합니다.따라서 AVX-512가 x86에 존재하는 이유를 알 수 있습니다.

사전 정의가 없으면 SIMD 폭이 넓어질수록 문제가 악화되어 대량의 opcode 확산, 성능 저하, 추가 전력 소비 및 불필요한 소프트웨어 [19]복잡성이 발생합니다.

한편 벡터 프로세서는 임의의 카운트 n에 대해 가변길이의 계산을 실행하도록 설계되어 있기 때문에 셋업이 거의 필요 없고 청소가 필요 없습니다.마스크가 있는 SIMD ISA와 비교해도 (단, 없음)setvl명령), 벡터 프로세서는 마지막 몇 가지 요소를 커버하기 위해 명시적 마스크 계산을 수행할 필요가 없기 때문에 훨씬 더 콤팩트한 코드를 생성합니다(아래 그림 참조).

사전 정의된 SIMD

(마스크가 가능한) SIMD ISA를 가정하고 SIMD 명령이 잘못 정렬된 데이터에 대처할 수 있다고 가정하면 명령 루프는 다음과 같습니다.

vloop:   # 마스크를 준비합니다.최소 ISA는 거의 없지만          t0, n, $4     ; t0 = min(n, 4)   교대하다     m, $1, t0     ; m = 1 < t0   후보선수       m, m, $1      ; m = (1<t0)-1   # 이제 m비트로 마스킹된 작업을 수행합니다.   로드 32x4  v1, x, m   로드 32x4  v2, y, m   멀티32x4   v1, a, v1, m  ; v1 : = v1 * a   추가 32x4   v3, v1, v2, m ; v3 : = v1 + v2   스토어 32x4 v3, y, m   # 다음 루프의 x, y 및 n 업데이트   추가      x, t0*4      ; x : = x + t0*4   추가      y, t0*4   가라앉다      n, n, t0     ;n:)n-t0   #루프?   jgz       n, 루프     ; n > 0일 경우 되돌아가다 출력:   리트 

여기를 통해 코드의지만 조금 복잡한 깨끗하다:적어도, 하지만, 설정 또는 정리:루프의 마지막 반복에, 객어 마스크 양쪽 0b0000, 0b0001, 0b0011, 0b0111 또는 0b1111, 사이에 0과 4단일 명령 다중 데이터 요소 작업 각각 수행하기로 귀결되는 설정을 할 것인가 볼 수 있다.한가지 추가적인 잠재적인 합병증:일부 리스크 ISAs, 대신 나뭇가지 혹은 scalar을 비교해서 하는 말을 사용할 필요가 있는"min"명령이 없다.

때문에 가변 길이 벡터와 술어 마스크를 사용하여 대처할 수 있어 어떻게predicated 단일 명령 다중 데이터 적어도 그 용어"벡털 수 있는"가치가 분명합니다.한"진정한"벡터 ISA최종 진화하는 단계, 하지만, ISA에 단일 명령 다중 데이터 너비의 증거 있지 않기 위해 떠나고 있다는 전적으로 하드웨어까지.

순수 벡터 ISA

Cray-style 벡터 ISAs RVV 같은 내용은 명령"setvl"(벡터 길이 설정)라고 불리는 사용된다.하드웨어 먼저:이 있을 실제 등록할 수 있거나 내부 루프(하이브리드 접근, 위에 언급한)한"벡터"에서 처리할 수 있다면 얼마나 많은 데이터 값을 정의합니다.이 최대 양(하드웨어의 수"차선")"MVL"(최대 벡터 길이)이라고 일컬어진다.참고는, SX-Aurora과 Videocore 4세에서 보듯이 MVL가 있을 것으로 실제 하드웨어 차선 수량 또는 가상 세계.(참고:ARMSVE2 자습서에 언급된, 프로그래머들이 고정된 벡터 너비:프로그래머가 알아야 할 결과적으로 MVL가 아니다 수량 추정하는 실수를 저지르지 않아야 한다.이것은 작은 단일 명령 다중 데이터 사고 방식년 후)이 황당할 수 있다.[어조]

처리되는 미결 데이터 요소의 수에 따라 setvl을 호출할 때 "setvl"은 최대 벡터 길이(MVL)로 제한하도록 허용되며, 따라서 후속 벡터 명령에서 하드웨어에 의해 처리 가능한 실제 를 반환하고 내부 특수 레지스터 "VL"을 동일한 양으로 설정합니다.ARM은 SVE2에 [20]관한 튜토리얼에서 이 기술을 '벡터 길이 불문' 프로그래밍이라고 부릅니다.

아래는 같은 SIMD 스타일의 루프를 위한 Cray 스타일의 벡터 어셈블러입니다.하드 코드화된 상수 대신 t0(VL의 편리한 복사가 포함되어 있어 다를 수 있음)이 사용됩니다.

vloop:   설정   t0, n      # VL=t0=min(MVL, n)   vld32   v0, x      부하 벡터 x 수   vld32   v1, y      부하 벡터 y 수   vmadd32 v1, v0, a  # v1 + = v0 * a   vst32   v1, y      # 스토어 Y   더하다     y, t0*4    # y를 VL*4만큼 앞당기다   더하다     x, t0*4    # 어드밴스×VL*4   후보선수     n, t0      # n - = VL (t0)   밧데리    n, 루프   n!= 0인 경우 # 반복 

이는 기본적으로 SIMD 버전(루프당 4개의 데이터 요소 처리) 또는 초기 스칼라 버전(하나만 처리)과 크게 다르지 않습니다.n은 아직 처리되는 데이터 요소의 수를 포함하지만, t0에는 VL의 복사본이 포함됩니다.t0은 각 반복에서 처리되는 숫자입니다.t0은 각 반복 후에 n에서 감산되며, n이 0이면 모든 요소가 처리된 것입니다.

Predicated SIMD 어셈블리 배리언트와 비교할 때 주의해야 할 점은 다음과 같습니다.

  1. setvl명령어가 그 안에 포함되어 있다.min설명
  2. SIMD 변형은 너비(4)를 마스크 생성과 SIMD 너비(load32x4 등)로 하드 코딩한 경우 벡터 ISA 등가에는 이러한 제한이 없습니다.따라서 벡터 프로그램은 휴대성이 뛰어나고 벤더에 의존하지 않으며 미래에도 대응할 수 있습니다.
  3. VL을 설정하면 벡터에 자동으로 적용되는 숨겨진 술어 마스크가 효과적으로 생성됩니다.
  4. 사전 SIMD를 사용하는 경우 마스크 비트 길이가 스칼라(또는 특수 마스크) 레지스터에 보유될 수 있는 것으로 제한되는 경우 벡터 ISA의 마스크 레지스터에는 이러한 제한이 없습니다.Cray-I 벡터는 1,000개 이상의 원소가 될 수 있습니다(1977년).

따라서 벡터 ISA가 명령의 수를 줄이는 방법을 매우 명확하게 알 수 있습니다.

또한 사전 정의된 SIMD 배리언트와 마찬가지로 x와 y에 대한 포인터는 둘 다 32비트 데이터를 가리키기 때문에 t0 x 4만큼 전진하지만 n은 직선 t0만큼 감소합니다.고정 사이즈의 SIMD 어셈블러에 비해 외관상의 차이는 거의 없습니다.x와 y는 하드 코드 상수 16만큼 전진하고 n은 하드 코드 4만큼 감소하기 때문에 처음에는 그 중요성을 인식하기 어렵습니다.그 차이는 벡터 하드웨어가 4개의 동시 연산을 할 수 있거나 64개 또는 10,000개가 모두 동일한 벡터 어셈블러일 수 있으며 SIMD 정리 코드는 아직 존재하지 않는다는 것을 깨닫는 데 있습니다.술어 대응 SIMD와 비교해도, 보다 콤팩트하고 명확하며, 우아하고, 자원을 적게 사용합니다.

이것은 훨씬 더 콤팩트한 프로그램일 뿐만 아니라(L1 캐시 크기를 절약할 수 있음), 앞서 언급한 바와 같이 벡터 버전은 ALU에 훨씬 더 많은 데이터 처리를 발행할 수 있으며, 명령 디코딩과 이슈는 유휴 상태로 둘 수 있기 때문에 전력을 절약할 수 있습니다.

또한 함수에 들어가는 요소의 수는 0부터 시작할 수 있습니다.그러면 벡터 길이가 0으로 설정됩니다. 그러면 실행 시 모든 벡터 명령이 효과적으로 비활성화되어 no-ops로 바뀝니다.따라서 복제되지 않은 SIMD와 달리 처리할 요소가 없는 경우에도 불필요한 정리 코드가 발생하지 않습니다.

벡터 축소 예시

이 예에서는 리덕션을 수반하는 알고리즘으로 시작합니다.앞의 예시와 마찬가지로 먼저 스칼라 명령으로 표시되고 다음으로 SIMD, 마지막으로 벡터 명령으로 표시됩니다.이거는 c부터 시작됩니다.

무효 (size_t n, 인트 a, 컨스턴트 인트 x[]) {     인트 y = 0;     위해서 (size_t i = 0; i < > n; i++)         y += x[i];     돌아가다 y; } 

여기서 어큐뮬레이터(y)를 사용하여 어레이 내의 모든 값 x를 집계한다.

스칼라 어셈블러

이것의 스칼라 버전에서는 x가 각각 로드되고 y에 추가되며 루프가 발생합니다.

  세트     y, 0     ; y는 0으로 초기화됨 루프:   로드32  r1, x    ; 32비트 데이터 1개를 로드합니다.   추가 32   y, y, r1 ; y : = y + r1   추가    x, x, $4 ; x : = x + 4   가라앉다    n, n, $1 ; n : = n - 1   jgz     n, 고리  ; n > 0인 경우 루프백합니다. 출력:   리트 y            ; 결과 y를 반환합니다. 

이것은 매우 간단하다."y"는 0에서 시작하여 32비트 정수를 r1에 1개씩 로드하고 y에 추가한 후 어레이 "x"의 주소가 어레이 내의 다음 요소로 이동합니다.

SIMD 저감

여기서부터 문제가 시작됩니다.SIMD는 설계상 "요소 간" 산술 연산을 수행할 수 없습니다.한 SIMD 레지스터의 요소 0을 다른 레지스터의 요소 0에 추가할 수 있지만 요소 0을 다른 요소 0에 추가할 수는 없습니다.이로 인해 잠재적인 구현에 몇 가지 심각한 제한이 있습니다.단순화를 위해 n은 정확히 8이라고 가정할 수 있습니다.

  추가      r3, x, $16 ; x의 2번째 4번째의 경우   로드 32x4  v1, x      ; x의 첫 번째 4   로드 32x4  v2, r3     ; x의 2번째 4번째   추가 32x4   v1, v2, v1 ; 2개의 그룹 추가 

이 시점에서 4개의 추가가 수행되었습니다.

  • x[0]+x[4]- 첫 번째 SIMD ADD : 첫 번째 그룹의 요소 0을 두 번째 그룹의 요소 0에 추가
  • x[1]+x[5]- 두 번째 SIMD ADD : 첫 번째 그룹의 요소 1을 두 번째 그룹의 요소 1에 추가
  • x[2]+x[6]- 세 번째 SIMD ADD : 첫 번째 그룹의 요소 2를 두 번째 그룹의 요소 2에 추가
  • x[3]+x[7]- 네 번째 SIMD ADD : 첫 번째 그룹의 요소 3을 두 번째 그룹의 요소 2에 추가

하지만 4폭 SIMD는 설계상 추가가 불가능하기 때문에x[0]+x[1]예를 들어, 범용 IAXPY 루프를 위해 SIMD를 사용하는 일반적인 사례와 마찬가지로 상황은 빠르게 악화됩니다.4개의 부분 결과를 종합하면, 2개의 폭 SIMD를 사용하고, 그 후 단일 스칼라 추가를 통해 최종적으로 답을 도출할 수 있지만, 종종 마지막 스칼라 계산이 수행되기 전에 전용 SIMD 레지스터에서 데이터를 전송해야 한다.

일반 루프(고정되지 않음)를 사용하더라도 4폭 SIMD를 사용하는 유일한 방법은 4개의 개별 "스트림"을 가정하는 것입니다. 각 스트림은 4개의 요소로 오프셋됩니다.마지막으로, 4개의 부분적인 결과를 합산해야 한다.그 외의 기술에는 셔플이 포함됩니다.AVX-512 의 「수평 합계」[21][22]의 방법에 대해서는, 온라인의 예를 참조해 주세요.

프로그램의 크기와 복잡성 외에도 부동소수점 연산이 수반될 경우 추가적인 잠재적 문제가 발생합니다. 즉, 값이 엄밀한 순서(4개의 부분 결과)로 합계되지 않는다는 사실이 반올림 오류를 초래할 수 있습니다.

벡터 ISA 절감

벡터 명령어 세트에는 ISA에 산술적 감소 연산이 내장되어 있습니다.n이 최대 벡터 길이보다 작거나 같다고 가정할 경우 다음 세 가지 명령만 필요합니다.

  설정      t0, n  # VL=t0=min(MVL, n)   vld32      v0, x  부하 벡터 x 수   vredadd32  y, v0  # y에 감소 추가 

n이 최대 벡터 길이보다 클 때의 코드는 그다지 복잡하지 않으며 첫 번째 예('IAXPY')와 유사한 패턴입니다.

  세트     y, 0 vloop:   설정   t0, n      # VL=t0=min(MVL, n)   vld32   v0, x      부하 벡터 x 수   vredadd32 y, y, v0 # 모든 x를 y에 더하다   더하다     x, t0*4    # 어드밴스×VL*4   후보선수     n, t0      # n - = VL (t0)   밧데리    n, 루프   n!= 0인 경우 # 반복   리트 y 

알고리즘의 심플함은 SIMD에 비해 현저합니다.IAXPY의 예와 마찬가지로 알고리즘은 길이에 구애받지 않습니다(최대 벡터 길이가 1인 Embedded 구현에서도 마찬가지).

하드웨어에 실장할 경우 올바른 답변이 도출될 것이 확실할 경우 병렬로 감소를 수행할 수 있습니다.일부 벡터 ISA는 프로그래머가 잠재적인 반올림 오류가 중요하지 않고 [23]낮은 지연 시간이 중요하다는 것을 알고 있을 때 명시적인 옵션으로 병렬 감소 모드를 제공합니다.

이 예에서는 벡터 프로세서의 기능에서 영감을 얻은 대부분의 상용 GPU를 포함한 진정한 벡터 프로세서와 SIMD 프로세서 간의 중요한 근본적인 차이를 다시 한 번 강조합니다.

사례에서 얻은 통찰력

벡터 프로세서를 표방하는 어떤 SIMD 프로세서와 비교해도 프로그램 사이즈의 축소 순서는 거의 충격적입니다.그러나 ISA 레벨에서의 이 우아한 수준은 하드웨어 레벨에서의 가격표가 매우 높습니다.

  1. IAXPY의 예에서 볼 수 있는 것은 SIMD 프로세서가 잘못 정렬된 메모리 액세스를 회피함으로써 내부 하드웨어를 단순화할 수 있는 것과 달리 벡터 프로세서는 이러한 단순화를 회피할 수 없다는 것입니다: 벡터 로드와 스토어가 정상적으로 동작하는 것에 본질적으로 의존하는 알고리즘이 작성됩니다.벡터
  2. 축소 예에서는 허가 명령과는 별도로 SIMD는 정의상 차선간 연산을 완전히 회피하고 있는 것을 알 수 있지만(요소0은 다른 요소0에만 추가할 수 있습니다), 벡터 프로세서는 이 문제를 정면으로 해결합니다.프로그래머가 소프트웨어에서 해야 할 일(데이터를 올바른 "레인"으로 바꾸기 위해 셔플 및 기타 기술을 사용하여) 벡터 프로세서가 하드웨어에서 자동으로 수행해야 하는 작업입니다.

전체적으로 볼 때 다음 중 하나를 선택할 수 있습니다.

  1. 복잡한 소프트웨어와 심플한 하드웨어(SIMD)
  2. 심플한 소프트웨어와 복잡한 하드웨어(프로세서 탑재)

이러한 극명한 차이가 벡터 프로세서와 SIMD를 가진 프로세서를 구별하는 것입니다.

벡터 프로세서의 기능

많은 SIMD ISA가 다음 목록에서 차용하거나 영감을 얻은 경우 벡터 프로세서의 일반적인 기능은 다음과 같습니다.[24][25][26]

  • 벡터 로드저장 – 레지스터 간 설계(스칼라 프로세서의 로드 스토어 아키텍처와 유사)를 가진 벡터 아키텍처에는 메모리와 벡터 레지스터 간에 여러 요소를 전송하는 명령이 있습니다.통상, 복수의 어드레싱 모드가 서포트되고 있습니다.유닛 스트라이드 어드레싱 모드는 필수적입니다.현대 벡터아키텍처는 일반적으로 임의의 일정한 스텝과 산란/수집(인덱스화라고도 불립니다) 어드레싱 모드를 지원합니다.고급 아키텍처에는 세그먼트 부하 및 저장소의 지원 및 표준 벡터 부하 및 저장소의 고장 우선 변형도 포함될 수 있습니다.세그먼트 로드는 메모리로부터 벡터를 읽어냅니다.여기서 각 요소는 복수의 멤버를 포함한 데이터 구조입니다.데이터 구조(요소)에서 부재를 추출하고 추출된 부재를 각각 다른 벡터 레지스터에 배치한다.
  • 마스크된 작업 – 술어 마스크는 브랜치에 의존하지 않고 병렬 if/then/else 구성을 허용합니다.이를 통해 조건문을 가진 코드를 벡터화할 수 있습니다.
  • 압축확장 – 보통 비트 마스크를 사용하여 데이터는 마스크 내의 비트가 설정 또는 클리어되었는지 여부에 따라 선형으로 압축 또는 확장(재전송)됩니다.또한 항상 시퀀셜 순서를 유지하며 값이 중복되지 않습니다(퍼머트라고도 함).이러한 순서는, AVX-512 로 기능합니다.
  • Register Gather, Satter(일명 permute)[27] – 압축/확장 테마의 덜 제한적인 일반적인 변형으로, 대신 한 벡터가 다른 벡터의 "순서 변경"에 사용할 지수를 지정합니다.수집/산란은 압축/팽창보다 구현이 더 복잡하고 본질적으로 비순차적이어서 벡터 체인을 방해할 수 있습니다.수집-산란 메모리 로드/저장 모드와 혼동하지 않도록 수집/산란 벡터 연산은 벡터 레지스터에 작용하며 대신 종종 퍼머트 명령이라고 합니다.
  • 스플랫과 추출 – 스칼라와 벡터 간의 상호작용에 도움이 됩니다.스칼라 및 벡터 간에는 각각 하나의 값을 브로드캐스트하거나 벡터로부터1개의 항목을 추출합니다.
  • Iota – 매우 단순하고 전략적으로 유용한 명령으로 순차적으로 감소합니다. 즉, 연속적인 요소로 증가합니다.보통 0부터 시작해요
  • 축소반복 – 벡터에 대해 맵 축소를 수행하는 연산(예를 들어 전체 벡터의 최대값을 찾거나 모든 요소를 합함)반복은 형식입니다.x[i] = y[i] + x[i-1]여기서 감소는 형식입니다.x = y[0] + y[1]… + y[n-1]
  • 매트릭스 멀티플 지원– 메모리로부터 데이터를 알고리즘으로 로드하거나 벡터 요소에 대한 통상적인 선형 액세스를 재정렬(리매핑)하거나 "어큐뮬레이터"를 제공함으로써 임의의 크기의 매트릭스를 효율적으로 처리할 수 있습니다.IBM POWER10은 정확한 SIMD 크기에 맞지 않는 임의의 매트릭스 너비에 대해 레지스터 파일 [29][30]리소스를 낭비하는 데이터 반복 기법이 필요하지만 MMA[28] 명령을 제공합니다.NVidia는 고급 Matrix CUDA API를 제공하지만 내부 세부 정보는 제공되지 [31]않습니다.가장 자원 효율이 높은 기술은 선형 벡터 데이터에 대한 액세스를 인플레이스 재정렬하는 것입니다.
  • 고급 산술 형식 – 대부분의 경우 Galois 필드 산술이 포함되지만 이진 코드화된 10진수 또는 10진수 고정 소수점, 병렬 반입 및 반출을 지원하여 훨씬 더 큰(임의 정밀도) 산술 연산을 지원합니다.
  • 비트 조작 – 비트 레벨 치환 조작, 비트 필드 삽입 및 추출, 원심 분리 조작, 인구 수 등의 벡터화 버전을 포함합니다.

GPU 벡터 처리 기능

삼각 연산을 필요로 하는 많은 3D 셰이더 애플리케이션에서 공통 연산을 위한 짧은 벡터(RGB, ARGB, XYZ, XYZW)는 벡터 프로세서에 있는 것 외에 일반적으로 최신 GPU에서 다음을 지원합니다.

  • 서브벡터 – 일반적으로 2개, 3개 또는 4개의 서브요소(vec2, vec3, vec4)를 포함할 수 있습니다.여기서 술어 마스크의 임의의 비트가 서브벡터의 요소가 아닌 vec2/3/4 전체에 적용됩니다.서브벡터는 RISC-V RVV(LMUL)[32]에도 도입됩니다.서브벡터는 Vulkan SPIR-V 사양에 필수적인 부분입니다.
  • 서브벡터 스위즐 – 서브요소를 올바른 SIMD "랜"으로 이동하기 위한 별도의 명령(비용이 많이 드는 낭비) 없이 서브벡터 간 계산을 가능하게 하고 사전 정의 마스크 비트를 저장할 수 있는 "레인 셔플링"이라고도 합니다.실제로 이는 3D Shader 바이너리에 많은 기능이 있는 서브벡터의 실행 중 미니 퍼뮤트이며, Vulkan SPR-V 사양에 포함될 정도로 중요합니다.Broadcom Videocore IV는 "레인 로테이션"[33]이라는 용어를 사용하며, 다른 업계에서는 "스위즐"[34]이라는 용어를 사용합니다.
  • 초월 – 사인, 코사인로그같은 삼각 연산은 많은 까다로운 HPC 워크로드보다 3D에서 훨씬 더 많이 특징지어집니다.그러나 픽셀 좌표 연산이 단순히 높은 정밀도를 필요로 하지 않는 GPU의 경우 3D 정확도보다 속도가 훨씬 더 중요합니다.Vulkan 사양은 이를 인식하고 GPU 하드웨어가 전력 소비를 줄일 수 있도록 놀라울 정도로 낮은 정확도 요건을 설정합니다.MIPS-3D 확장에서는 단순히 필요하지 않은 정확도 감소 개념을 탐구합니다.

우선 장애(또는 장애)

ARM SVE2 및 RISC-V RVV에 도입된 것은 투기성 순차 벡터 부하 개념입니다.ARM SVE2에는 "First Fault Register"[35]라는 이름의 특수 레지스터가 있으며, 여기서 RVV는 벡터 길이(VL)[36]를 수정(트렁크)합니다.

first의 기본 원칙은 대규모 순차 벡터 로드를 시도하지만 실제 로딩된 을 메모리 장애를 일으키지 않고 성공하는 양 또는 단순히 가장 편리한 양(0보다 큰 양)으로 임의로 잘라내는 것입니다.중요한 요인은 후속 명령이 통지되거나 실제로 성공한 로드 수를 정확하게 결정할 수 있다는 것입니다. 이 수량을 사용하여 실제로 로드된 데이터에 대한 작업만 수행합니다.

이 상황을 SIMD와 대조해 봅시다.SIMD는 고정(불변성) 부하폭 및 고정 데이터 처리폭으로 페이지 경계를 넘는 부하에 대처할 수 없습니다.SIMD가 실제로 성공한 부하에 대응할 수 없다고 해도 역설적으로 SIMD 프로그램이 사전에 (각 내부 루프에서)를 찾아내려고 시도하고 있는지조차 t마다 확인합니다.ime) 최적으로 성공할 수 있는 것은, 이러한 명령어는, 필연적으로, 중요한 내부 루프의 일부가 되기 때문에, 퍼포먼스를 방해할 뿐입니다.

이는 first가 왜 그렇게 혁신적인지 암시하기 시작하며, memcpy 또는 strcpy로 가장 잘 설명됩니다. IBM POWER9의 경우 strncpy를 구현하기 위한 수동 최적화 명령의 수가 [37]240개를 초과합니다.이와는 대조적으로, 수작업으로 최적화된 RVV 어셈블러에서 동일한 strncpy 루틴은 단지 22개의 [38]명령입니다.

위의 SIMD 예에서는 메모리 끝에서 너무 많은 값을 읽으려고 하면 오류가 발생할 수 있습니다.또, 마찬가지로 경계를 넘나드는 것으로, 대량의 페이지나 잘못 정렬된 장해가 발생할 수도 있습니다.이와는 대조적으로 벡터 아키텍처가 로드하는 요소의 수를 자유롭게 결정할 수 있도록 함으로써 strncpy의 첫 번째 부분은 처음에는 최적 메모리 경계에서 시작했지만 루프의 후속 반복에서 벡터화된 메모리 판독의 배치가 기본 캐시와 최적으로 정렬되도록 충분한 부하만 반환할 수 있습니다.및 가상 메모리 배열입니다.또한 하드웨어는 현재 루프에서 데이터가 처리되고 있는 동안 다음 가상 메모리 페이지를 준비하는 추측 실행을 통해 페이지 경계에서 특정 루프 반복의 메모리 읽기를 정확하게 종료할 수 있습니다(비용이 많이 드는 두 번째 TLB 검색 회피).이 모든 것은 프로그램 자체가 아니라 하드웨어에 [39]의해 결정됩니다.

퍼포먼스와 속도 향상

r을 벡터 속도비, f를 벡터화비라고 하자.벡터 단위가 64개의 숫자의 배열을 추가하는 데 걸리는 시간이 동등한 스칼라 단위보다 10배 빠르면 r = 10이다.또한 프로그램의 총 연산수가 100이고 그 중 10개만 스칼라(벡터화 후)이면 f = 0.9, 즉 작업의 90%가 벡터 단위로 이루어진다.다음과 같은 속도를 달성할 수 있습니다.

따라서 벡터 유닛의 성능이 매우 높더라도( \ r = \ 1/(1 -) ( \ 1/ ( 1 - f)의 속도 상승이 존재하므로 비율 f가 성능에 매우 중요합니다.이 비율은 메모리 내의 요소의 인접관계와 같은 컴파일 효율에 따라 달라집니다.

「 」를 참조해 주세요.

외부 링크

레퍼런스

  1. ^ Malinovsky, B.N. (1995). The history of computer technology in their faces (in Russian). Kiew: Firm "KIT". ISBN 5-7707-6131-8.
  2. ^ MIAOW 수직 연구 그룹
  3. ^ MIAOW GPU
  4. ^ Miyaoka, Y.; Choi, J.; Togawa, N.; Yanagisawa, M.; Ohtsuki, T. (2002). An algorithm of hardware unit generation for processor core synthesis with packed SIMD type instructions. Asia-Pacific Conference on Circuits and Systems. Vol. 1. pp. 171–176. doi:10.1109/APCCAS.2002.1114930. hdl:2065/10689.
  5. ^ "Riscv-v-spec/V-spec.adoc at master · riscv/Riscv-v-spec". GitHub.
  6. ^ Cray의 개요
  7. ^ RISC-V RVV ISA
  8. ^ SX-Arora의 개요
  9. ^ "Documentation – Arm Developer".
  10. ^ "Vector Architecture". 27 April 2020.
  11. ^ 벡터 및 SIMD 프로세서, 슬라이드 12-13
  12. ^ 어레이와 벡터 프로세싱, 슬라이드 5~7
  13. ^ SIMD vs 벡터 GPU, 슬라이드 22-24
  14. ^ Patterson, David A.; Hennessy, John L. (1998). Computer Organization and Design: the Hardware/Software Interface page 751-2 (2nd ed.). Morgan Kaufmann. p. 751-2. ISBN 155860491X.
  15. ^ "Riscv-v-spec/V-spec.adoc at master · riscv/Riscv-v-spec". GitHub.
  16. ^ 비디오코어 IV 프로그래머 매뉴얼
  17. ^ Jeff Bush의 Videocore IV QPU 분석
  18. ^ "Coding for Neon - Part 3 Matrix Multiplication".
  19. ^ 유해하다고 생각되는 SIMD
  20. ^ ARM SVE2 튜토리얼
  21. ^ "Sse - 1-to-4 broadcast and 4-to-1 reduce in AVX-512".
  22. ^ "Assembly - Fastest way to do horizontal SSE vector sum (Or other reduction)".
  23. ^ "Riscv-v-spec/V-spec.adoc at master · riscv/Riscv-v-spec". GitHub.
  24. ^ Cray의 개요
  25. ^ RISC-V RVV ISA
  26. ^ SX-Arora의 개요
  27. ^ RVV 레지스터 수집 산란 지침
  28. ^ "IBM's POWER10 Processor - William Starke & Brian W. Thompto, IBM". YouTube. Archived from the original on 2021-12-11.
  29. ^ Moreira, José E.; Barton, Kit; Battle, Steven; Bergner, Peter; Bertran, Ramon; Bhat, Puneeth; Caldeira, Pedro; Edelsohn, David; Fossum, Gordon; Frey, Brad; Ivanovic, Nemanja; Kerchner, Chip; Lim, Vincent; Kapoor, Shakti; Tulio Machado Filho; Silvia Melitta Mueller; Olsson, Brett; Sadasivam, Satish; Saleil, Baptiste; Schmidt, Bill; Srinivasaraghavan, Rajalakshmi; Srivatsan, Shricharan; Thompto, Brian; Wagner, Andreas; Wu, Nelson (2021). "A matrix math facility for Power ISA(TM) processors". arXiv:2104.03142 [cs.AR].
  30. ^ Krikelis, Anargyros (1996). "A Modular Massively Parallel Processor for Volumetric Visualisation Processing". High Performance Computing for Computer Graphics and Visualisation. pp. 101–124. doi:10.1007/978-1-4471-1011-8_8. ISBN 978-3-540-76016-0.
  31. ^ "CUDA C++ Programming Guide".
  32. ^ LMUL > 1 (RVV)
  33. ^ 미국 특허 포기 US20110227920-0096
  34. ^ 비디오코어 IV QPU
  35. ^ ARM SVE2의 개요
  36. ^ RVV 장애 우선 부하
  37. ^ libc6에 패치하여 최적화된 POWER9 strncpy 추가
  38. ^ RVV strncpy 예시
  39. ^ ARM SVE2 용지 By N.스티븐스