콘텐츠로 바로가기

SIMD & Vector CPU Extensions

하나의 명령어로 거대한 데이터 배열을 한꺼번에 처리하는 SIMD 방식과 AVX, NEON 등 현대 CPU의 벡터 연산 하드웨어 가속을 다루는 학습 노드입니다.

Article
M

Me

hyunyoun's Blog

computer-architecture-embedded-systemscomputer-architectureembedded-systemsparallelmulticore-mechanicssimdvector-cpu-extensionsdigital-logic9 min read

1. Overview

SIMD와 벡터 CPU 확장(SIMD & Vector CPU Extensions, SVE)은 1클럭에 1개의 데이터만 처리하던 스칼라(Scalar) 방식의 한계를 줄이고, 256비트나 512비트 벡터 레지스터에 여러 데이터를 묶어 한 번의 명령으로 8개, 16개의 연산을 동시에 처리하는 데이터 병렬성(Data Level Parallelism, DLP) 엔진입니다.

학습자는 멀티미디어 처리와 딥러닝 텐서(Tensor) 연산의 핵심인 SIMD(Single Instruction, Multiple Data) 아키텍처의 물리적 구조를 살펴보고, 인텔의 AVX/SSE나 ARM의 NEON 명령어 세트를 분석합니다. 이어 루프 구조를 SIMD 인스트럭션으로 컴파일되기 쉽게 조정하는 벡터라이제이션(Vectorization) 최적화 기법을 익혀, 단순한 for 루프를 하드웨어 레벨에서 더 빠르게 처리하는 로우 레벨 튜닝 역량을 확보합니다.

2. Scope & Boundaries

In-Scope

  • 플린의 분류(Flynn's Taxonomy): SISD, SIMD, MISD, MIMD의 기하학적 차이.
  • SIMD 하드웨어 아키텍처 (SIMD Physics): 벡터 레지스터(Vector Registers: 128/256/512-bit), 팩형 데이터(Packed Data Type), 레인(Lanes).
  • 명령어 확장 규격 (ISA Extensions): x86 SSE/AVX/AVX-512, ARM NEON/SVE 구조 및 본질.
  • 루프 벡터화 로직 (Loop Vectorization): 컴파일러 자동 벡터화(Auto-vectorization), 데이터 정렬(Data Alignment) 요구 사항, 인트린식(Intrinsics) 함수 프로그래밍.

Out-of-Scope

  • GPU 아키텍처 및 SIMT: 수천 개의 코어가 스레드 단위로 도는 GPU의 CUDA/OpenCL 프로그래밍 \rightarrow 12-07. Graphics Processing Unit (GPU) Physics 영역.
  • 분산 노드 데이터 병렬화: 하둡(Hadoop)이나 맵리듀스(MapReduce)처럼 여러 서버에 데이터를 나누어 처리하는 소프트웨어 클러스터링 \rightarrow 07-03. Distributed Storage & Big Data Physics 영역.

Boundaries

  • SIMD vs. Multicore/MIMD (02-03-01): 멀티코어 파이프라인(MIMD)은 여러 코어가 각자 다른 명령어와 데이터를 처리하는 병렬성입니다. SIMD는 하나의 명령어가 여러 레인(ALU Lane)에 같은 연산을 동시에 적용해, 규칙적인 데이터 배열 연산에서 높은 하드웨어 효율을 얻는 방식입니다.

3. Counterexample

  • 조건 분기에 의한 SIMD 레인 낭비 (Divergence Fallacy): 이미지 픽셀 8개를 SIMD로 한 번에 밝기 변환하려는데, 루프 안에 if (pixel > 128) 같은 분기문이 섞인 경우입니다. SIMD는 '하나의 명령어'로 통일되어야 하므로 레인(Lane)별로 다른 길을 갈 수 없습니다. 하드웨어는 조건을 만족하지 않는 레인의 결과를 버리도록 비트마스킹(Masking)하며 실행하므로, 일부 레인만 유효한 상황에서는 나머지 레인의 연산 능력(ALU)이 낭비되어 스칼라(Scalar)보다 느려질 수 있습니다.
  • 비정렬 메모리 로드 비용 (Unaligned Memory Access): 256비트(32바이트) YMM 레지스터에 배열 데이터를 한 번에 가져오려고(Load) AVX 인트린식을 썼지만, 배열의 시작 주소가 32바이트 경계(Boundary)에 맞지 않는 경우입니다. 하드웨어가 비정렬 데이터를 읽기 위해 캐시 라인 2개를 걸쳐 접근하면서 클럭 페널티(Penalty)가 커지고, 일부 명령이나 환경에서는 세그멘테이션 폴트(Segmentation Fault)가 발생할 수 있습니다.

4. Prerequisites

  • ALU와 레지스터 파일 (Basic): 32비트 ALU 여러 개를 옆으로 이어 붙여 거대한 256비트 전선망을 만든 것이 SIMD이므로, 데이터 패스의 물리를 직관하고 있어야 합니다. (02-01-02 IFR, 02-01-03 ADP)

5. Learning Map

Sequence Core Cluster Objective & Description Evidence (BoK)
1 Data Level Parallelism 반복 루프 안의 독립적인 데이터 연산을 묶어 처리할 수 있는 조건을 파악합니다. P1
2 SIMD Hardware 256비트 레지스터 안에 32비트 float 8개를 팩(Pack)으로 담고, 여러 ALU 레인이 동시에 연산하는 구조를 살펴봅니다. P5
3 Vectorization & Alignment 컴파일러가 루프를 자동 벡터화(Auto-vectorization)하도록 유도하고, 메모리 주소 경계를 맞추는(Alignment) 튜닝을 분석합니다. Industry/C++
4 Intrinsics Programming C 언어에서 AVX 인트린식(_mm256_add_ps)을 직접 호출해 컴파일러가 생성할 하드웨어 명령을 명시적으로 제어합니다. Industry/DL

6. Learning Topics

Basic

Core Topic 01: 데이터 병렬성과 플린의 분류 (DLP & Flynn's Taxonomy)

  • Why to Learn: 그래픽 렌더링이나 머신러닝 행렬 곱셈에서 반복되는 규칙적인 연산을, 코어 개수를 늘리지 않고 단일 코어 안에서 더 빠르게 처리하는 아키텍처 원리를 이해하기 위해서입니다.
  • What to Learn:
    • Concepts: SISD(Single Instruction Single Data), SIMD(Single Instruction Multiple Data), MISD, MIMD(멀티코어).
    • Skills: 데이터 레벨 병렬성(Data Level Parallelism, DLP) 식별.
    • Tools: 벡터(Vector) 연산과 스칼라(Scalar) 연산 궤적 비교.
    • Trade-offs: 스레드를 여러 개 쓰는 MIMD 방식의 범용성 및 컨텍스트 스위칭 오버헤드 vs 조건문이 섞이면 효율이 낮아지지만 단순 수학 배열 연산에서는 트랜지스터 대비 성능비가 높은 SIMD의 특화 구조.
  • How to Learn:
    • 1단계: A[i]=B[i]+C[i]A[i] = B[i] + C[i] 라는 루프에서 i=0i=0일 때의 연산과 i=1i=1일 때의 연산이 서로 독립적(No Loop-carried Dependency)이므로 함께 처리해도 데이터 의존성이 깨지지 않는 DLP 상태를 분석합니다.
    • 2단계: 명령어 Fetch/Decode 경로는 공유하고, 끝단의 ALU(실행 유닛) 레인을 여러 개 두어 같은 명령을 여러 데이터에 적용하는 SIMD의 구조를 살펴봅니다.
  • Implement: NN 사이즈의 배열 2개를 더하는 파이썬 코드에서, 1개씩 순회하는 스칼라 for 루프와 NumPy 라이브러리(C=A+B, C 레벨에서 SIMD 활용) 배열 연산 간의 실행 시간(Time) 차이를 배열 크기별로 비교하는 벤치마크 작성.

Core Topic 02: 벡터 레지스터와 하드웨어 레인 아키텍처 (SIMD Physics)

  • Why to Learn: 인텔 CPU 스펙 시트에 적힌 SSE(128비트), AVX2(256비트), AVX-512(512비트)가 무엇을 의미하며, 레지스터 파일과 실행 레인이 어떻게 확장되는지 이해하기 위해서입니다.
  • What to Learn:
    • Concepts: 벡터 레지스터(XMM/YMM/ZMM), 팩형 데이터(Packed Data), 레인(Lanes).
    • Skills: 데이터 쪼개기(예: 256비트 = 32비트 Float ×\times 8개, 64비트 Double ×\times 4개).
    • Tools: AVX 레지스터 맵.
    • Trade-offs: 512비트(ZMM) 레지스터로 연산 폭을 늘리면 한 명령의 처리량은 커지지만, 전력과 발열 부담 때문에 CPU가 클럭을 낮추는(Downclocking) AVX-512의 성능 딜레마가 생길 수 있습니다.
  • How to Learn:
    • 1단계: 256비트(YMM) 레지스터 안에 32비트 float 값 8개를 팩(Packed) 형태로 채워 넣는 메모리 적재(Load) 구조를 분석합니다.
    • 2단계: vaddps(Vector Add Packed Single) 명령어가 실행되면, YMM0과 YMM1 레지스터의 같은 위치에 있는 8쌍의 데이터(레인)가 여러 ALU를 통해 동시에 더해져 YMM2에 저장되는 병렬성을 살펴봅니다.
  • Implement: 256비트(32바이트)를 모사하는 바이트배열(Bytearray) 객체를 만들고, load_float8() 메서드를 통해 float 8개를 팩(Pack)하고, simd_add()를 호출하면 루프 없이 zip 처리로 8쌍을 한 방에 더하는 가상 YMM 레지스터 파이썬 클래스 구현.

Practical

Core Topic 03: 데이터 정렬과 컴파일러 자동 벡터화 (Vectorization & Alignment)

  • Why to Learn: C/C++ for 루프를 컴파일러(GCC/Clang)가 SIMD 기계어로 자동 매핑(Auto-vectorize)하게 유도하려면, 코드에서 어떤 조건을 만족해야 하는지 알아야 합니다.
  • What to Learn:
    • Concepts: 자동 벡터화(Auto-vectorization), 메모리 정렬(Memory Alignment), 루프 롤링/언롤링 결합.
    • Skills: 포인터 앨리어싱(Pointer Aliasing) 제거(restrict 키워드), 32-byte Alignment 할당(_mm_malloc).
    • Tools: 컴파일러 최적화 리포트(-fopt-info-vec).
    • Trade-offs: 메모리 경계를 32바이트(AVX) 단위로 맞추면 벡터 Load 한 번으로 데이터를 빠르게 가져올 수 있지만 앞뒤에 자투리 메모리가 생길 수 있습니다. 반대로 정렬을 맞추지 않으면 공간은 아낄 수 있어도 CPU가 두 번 읽어 조립하느라 사이클 비용이 커집니다.
  • How to Learn:
    • 1단계: 컴파일러 입장에서 포인터 A와 B가 가리키는 배열이 메모리에서 겹칠 가능성(Pointer Aliasing)이 있으면, 안전을 위해 벡터화를 포기하고 스칼라 경로를 택할 수 있음을 분석합니다.
    • 2단계: 배열 인자에 __restrict 키워드를 두어 겹치지 않는다는 정보를 제공하고, 데이터 의존성이 없는 순수(Pure) 수학 루프에서 GCC 최적화 리포트에 "Loop vectorized"가 뜨는 조건을 확인합니다.
  • Implement: A[i]=A[i1]+B[i]A[i] = A[i-1] + B[i] 처럼 앞 루프의 결과를 뒤 루프가 사용하는(Loop-carried Dependency) 코드는 SIMD 배열로 묶으면 결과가 달라질 수 있음을, 순차 계산 값과 벡터 묶음 계산 값을 콘솔에 비교 출력하여 벡터화 금지 조건(Hazard)을 증명.

Advanced

Core Topic 04: 인트린식(Intrinsics)을 통한 하드웨어 직접 호출

  • Why to Learn: 컴파일러가 자동 벡터화에 실패해 코드가 스칼라 경로로 남을 때, C++ 코드에서 어셈블리에 가까운 내장 함수(Intrinsics)를 직접 호출해 CPU의 SIMD 유닛을 명시적으로 사용하는 마이크로 튜닝이 필요할 수 있습니다.
  • What to Learn:
    • Concepts: 인트린식(Intrinsics), 벡터 타입(__m256, __m128i).
    • Skills: AVX Load/Store/Add/Mul 인트린식 함수 매핑, FMA(Fused Multiply-Add).
    • Tools: Intel Intrinsics Guide.
    • Trade-offs: 인트린식을 쓰면 특정 하드웨어의 성능을 세밀하게 활용할 수 있지만, x86 AVX 코드가 ARM 프로세서(스마트폰/맥북)에서는 컴파일되지 않아 이식성(Portability)이 크게 낮아질 수 있습니다.
  • How to Learn:
    • 1단계: _mm256_loadu_ps (Load) \rightarrow _mm256_add_ps (Add) \rightarrow _mm256_storeu_ps (Store)처럼 C 코드가 특정 SIMD 명령과 1<1에> 가깝게 매핑되는 흐름을 확인합니다.
    • 2단계: 곱하기 연산과 더하기 연산을 따로 수행할 때와, FMA(Fused Multiply-Add, A×B+CA \times B + C) 인트린식을 써서 한 명령으로 처리할 때의 레지스터 사용과 반올림 차이를 비교합니다.
  • Implement: 32개의 요소를 가진 가상 Float 배열에 대해, 4개씩 잘라서 Virtual_AVX_Add()라는 가짜 인트린식 래퍼(Wrapper) 함수를 강제 호출(루프 언롤링)하는 C-style 파이썬 시뮬레이션 코드를 작성하여, 컴파일러 튜닝 개입 없이 스칼라 대비 명령 호출 횟수(Call Count)가 1/4로 줄어드는 로그 도출.

7. Terminology

Term (EN / ko, abbr) 1문장 정의 단계(기본/권장/실무/심화) 역할/맥락 관련 개념 유사/대비/함께 사용 오해 포인트 Evidence(Primary/Secondary/Industry) Flags(core)
SIMD 단일 명령어로 여러 개의 데이터 포인트에 대해 동일한 물리적 연산을 병렬 수행하는 방식입니다. 기본 병렬 방식 Vectors SISD '멀티스레딩'과 다른 층위 P1:CS2023/Parallelism core
Lane (레인) 벡터 레지스터 내에서 독립적인 하나의 데이터 요소가 처리되는 물리적 구분 단위입니다. 추천 연산 구획 Element / Port Channel '도로 차선' 비유와 유사 Industry Extension core
Intrinsic 어셈블리 직접 작성 없이 고수준 언어에서 특정 하드웨어 벡터 명령을 1<1로> 호출하게 돕는 기능입니다. 실무 함수 인터페이스 Instruction Library '일반 라이브러리 함수'와 다름 Industry core
Masking 벡터 연산 시 특정 레인(Lane)의 결과만을 취하거나 버리도록 제어하는 하드웨어 필터링 물리입니다. 심화 조건부 제어 Predication Conditional '데이터 은폐'와 무관 Industry core

8. References

Primary

Secondary

  • [Intel Intrinsics Guide] — The interactive industry reference for developers.
  • [Real-World SIMD with NEON and AVX] — Practical optimization book.

Industry

  • [ARM NEON Programmer's Guide] — Essential for mobile/embedded dev.
  • [Intel 64 and IA-32 Architectures Instruction Set Reference - AVX] — Official spec.

9. Final Checklist

Primary

  • 단일 명령어 흐름에서 256비트 부동소수점 벡터 레지스터가 동시에 처리 가능한 float32 데이터 개수를 수리적으로 도출할 수 있는가? (P1)
  • SIMD 아키텍처가 전형적인 이미지 필터링(예: 흐림 효과)에서 스칼라 연산보다 물리적으로 왜 우월한지 데이터 패스 관점에서 입증 가능한가? (P1)

Secondary

  • 메모리 정렬(Memory Alignment)이 지켜지지 않았을 때, 하드웨어가 두 번의 메모리 트랜잭션을 수행해야만 하는 물리적 이유를 설명할 수 있는가?
  • 벡터 연산 중 '조건부 실행(if-else)'을 처리하기 위해 'Masking' 비트가 실제 ALU의 연산 결과 반영을 어떻게 물리적으로 차단하는지 소통 가능한가?

Industry

  • 딥러닝 추론 엔진(예: TensorFlow Lite) 최적화 시, 특정 CPU의 NEON 지원 여부에 따라 데이터 레이아웃을 'NCHW'에서 'NHWC'로 바꿀 때의 성능 이점을 제안할 수 있는가? (SFIA)
  • 암호화 알고리즘(AES 등) 구현 시, 하드웨어 내장 벡터 인스트럭션을 사용하여 소프트웨어 구현 대비 보안성과 성능이 동시에 향상됨을 물리적으로 증명할 수 있는가?

Digital Logic & Processor Physics

7 / 7