"벡터화"란 무엇입니까?


190

몇 번이나, 나는 matlab, fortran ...에서 다른 용어를 만났습니다 ...하지만 다른 것은 ... 그것이 무엇을 의미하는지, 그것이 무엇을 의미하는지 설명을 찾지 못했습니다. 여기에 묻습니다. 벡터화 란 무엇입니까? 예를 들어 "루프가 벡터화 됨"이란 무엇입니까?


답변:


225

많은 CPU에는 "벡터"또는 "SIMD"명령 세트가 있으며이 명령 세트는 2 개, 4 개 이상의 데이터 조각에 동시에 동일한 작업을 적용합니다. 최신 x86 칩에는 SSE 명령어가 있고 많은 PPC 칩에는 "Altivec"명령어가 있으며 일부 ARM 칩에도 NEON이라는 벡터 명령어 세트가 있습니다.

"벡터화"(단순화)는 어레이의 단일 요소를 N 번 처리하는 대신, 어레이의 4 개의 요소를 동시에 N / 4 배로 처리하도록 루프를 재 작성하는 프로세스이다.

(저는 현대 하드웨어가 직접 지원할 가능성이 가장 높기 때문에 4를 선택했습니다. "벡터화"라는 용어는 루프를 완전히 추상화하고 요소 대신 배열에서의 작동을 설명하는 고급 소프트웨어 변환을 설명하는 데에도 사용됩니다. 그들을 구성하는)


벡터화와 루프 언 롤링의 차이점 : 두 배열의 요소를 추가하고 결과를 세 번째 배열에 저장하는 다음과 같은 매우 간단한 루프를 고려하십시오.

for (int i=0; i<16; ++i)
    C[i] = A[i] + B[i];

이 루프를 풀면 다음과 같이 변환됩니다.

for (int i=0; i<16; i+=4) {
    C[i]   = A[i]   + B[i];
    C[i+1] = A[i+1] + B[i+1];
    C[i+2] = A[i+2] + B[i+2];
    C[i+3] = A[i+3] + B[i+3];
}

반면에 벡터화하면 다음과 같이 생성됩니다.

for (int i=0; i<16; i+=4)
    addFourThingsAtOnceAndStoreResult(&C[i], &A[i], &B[i]);

여기서 "addFourThingsAtOnceAndStoreResult"는 컴파일러가 벡터 명령어를 지정하기 위해 사용하는 내장 함수에 대한 자리 표시 자입니다. 일부 컴파일러는 이와 같은 매우 간단한 루프 를 자동 벡터화 할 수 있으며, 종종 컴파일 옵션을 통해 활성화 될 수 있습니다. 더 복잡한 알고리즘은 여전히 ​​좋은 벡터 코드를 생성하기 위해 프로그래머의 도움이 필요합니다.


11
루프 언 와인딩 / 언 롤링의 차이점은 무엇입니까?
Jeremy Powell

1
컴파일러가 롤링되지 않은 루프를 자동 벡터화하는 작업이 더 쉽다는 것이 사실이 아닙니까?
Nikos Athanasiou 2016 년

@NikosAthanasiou : 그럴듯하지만 일반적으로 컴파일러는 두 루프 모두 아주 간단하기 때문에 어느 한 루프를 자동 벡터화 할 수 있어야합니다.
Stephen Canon

1
@StephenCanon 일부 라인이 벡터화되었는지 여부를 어떻게 확인할 수 있습니까? objdump를 사용한다면 objdump의 출력에서 ​​무엇을 찾을 것입니까?
user1823664

3
@Shuklaswag : 벡터화는 컴파일러가 여러분을 위해 할 수있는 일이지만 프로그래머가 명시 적으로하는 일이기도합니다. OS는 관련이 없습니다.
Stephen Canon

32

벡터화는 스칼라 프로그램을 벡터 프로그램으로 변환하는 용어입니다. 벡터화 된 프로그램은 단일 명령어에서 여러 연산을 실행할 수있는 반면 스칼라는 한 번에 피연산자 쌍에서만 작동 할 수 있습니다.

에서 위키 피 디아 :

스칼라 접근법 :

for (i = 0; i < 1024; i++)
{
   C[i] = A[i]*B[i];
}

벡터화 된 접근 방식 :

for (i = 0; i < 1024; i+=4)
{
   C[i:i+3] = A[i:i+3]*B[i:i+3];
}

본질적으로 스칼라 접근 방식과 동일하지 않습니까? 구문과 루프 진행은 다르지만 여전히 4 배를 곱하고 있습니다. 그러나 어쨌든 CPU에는 벡터화라는 트릭을 수행하는 명령이 더 빠를 것입니다.
mskw

여기에 내 질문에 대답 할 것 같습니다. 컴파일러가이를 알면 벡터화 접근법의 구문은 벡터를 곱하는 최적화 된 CPU 명령어로 변환합니다. SIMD처럼.
mskw

10

단일 단계에서 숫자의 목록 또는 "벡터"에 대해 단일 수학 연산을 수행하는 기능을 나타냅니다. 과학적 컴퓨팅과 관련이 있기 때문에 Fortran에서 자주 볼 수 있습니다. 과학 컴퓨팅은 수퍼 컴퓨팅과 관련이 있으며 벡터화 된 산술이 처음 나타납니다. 오늘날 거의 모든 데스크탑 CPU는 인텔의 SSE와 같은 기술을 통해 어떤 형태의 벡터화 된 산술을 제공합니다. GPU는 또한 벡터화 된 산술 형식을 제공합니다.


7

벡터화 는 많은 양의 데이터를 효율적으로 처리해야하는 과학 컴퓨팅에 크게 사용됩니다.

실제 프로그래밍 응용 프로그램에서는 NUMPY에서 사용된다는 것을 알고 있습니다 (다른 확실하지 않음).

Numpy (python의 과학 컴퓨팅 패키지), 벡터화 사용 는 n 차원 배열의 빠른 조작을 를 , 일반적으로 배열 처리를 위해 내장 된 python 옵션으로 수행하면 속도가 느려집니다.

설명의 톤이 출력되지만, 여기에 무엇 벡터화 정의 AS IN NumPy와 도움말 페이지

벡터화는 코드에 명시 적 루핑, 인덱싱 등이 없음을 설명합니다. 물론 이러한 작업은 최적화 된 사전 컴파일 된 C 코드에서 "뒤에서"발생합니다. 벡터화 된 코드에는 다음과 같은 많은 장점이 있습니다.

  1. 벡터화 된 코드가 더 간결하고 읽기 쉽습니다

  2. 적은 코드 줄은 일반적으로 더 적은 버그를 의미합니다.

  3. 이 코드는 표준 수학 표기법과 더 유사합니다 (일반적으로 수학 구문을 올바르게 코딩하는 것이 더 쉬워 짐)

  4. 벡터화는 더 많은 "Pythonic"코드를 생성합니다. 벡터화가 없으면 코드가 비효율적이며 for 루프를 읽기 어려워집니다.


4

간단히 말하면 벡터화는 알고리즘을 최적화하여 프로세서에서 SIMD 명령어를 활용할 수 있음을 의미합니다.

AVX, AVX2 및 AVX512는 하나의 명령어로 여러 데이터에 대해 동일한 작업을 수행하는 명령어 세트 (인텔)입니다. 예를 들어. AVX512는 한 번에 16 개의 정수 값 (4 바이트)을 조작 할 수 있음을 의미합니다. 즉, 16 개의 정수로 구성된 벡터가 있고 각 정수에서 해당 값을 두 배로 늘리고 10을 더하려는 경우입니다. 일반 레지스터 [a, b, c]에 16 번 값을로드하고 동일한 작업을 수행하거나 16 개의 모든 값을 SIMD 레지스터 [xmm, ymm]에로드하여 동일한 작업을 수행하고 한 번만 작업을 수행 할 수 있습니다. 이를 통해 벡터 데이터 계산 속도를 높일 수 있습니다.

벡터화에서는 SIMD 작업을 수행하고 프로그램 속도를 높일 수 있도록 데이터를 리모델링하여이를 활용합니다.

벡터화의 문제 만 처리 조건입니다. 조건은 실행 흐름을 분기하기 때문입니다. 마스킹으로 처리 할 수 ​​있습니다. 조건을 산술 연산으로 모델링합니다. 예. 100보다 큰 값에 10을 더하고 싶다면 둘 중 하나입니다.

if(x[i] > 100) x[i] += 10; // this will branch execution flow.

또는 조건 벡터 c를 생성하는 산술 연산으로 조건을 모델링 할 수 있습니다.

c[i] = x[i] > 100; // storing the condition on masking vector
x[i] = x[i] + (c[i] & 10) // using mask

이것은 매우 간단한 예입니다 ... 따라서 c는 값에 따라 이진 연산을 수행하는 데 사용하는 마스킹 벡터입니다. 이것은 실행 흐름의 분기를 피하고 벡터화를 가능하게합니다.

벡터화는 병렬화만큼 중요합니다. 따라서 최대한 활용해야합니다. 현대의 모든 프로세서에는 많은 컴퓨팅 워크로드를위한 SIMD 명령이 있습니다. 벡터화를 사용하여 이러한 SIMD 명령어를 사용하도록 코드를 최적화 할 수 있습니다. 이는 현대 프로세서에서 사용 가능한 여러 코어에서 실행되도록 코드를 병렬화하는 것과 유사합니다.

pragma를 사용하여 코드를 벡터화 할 수있는 OpenMP에 대해 언급하고 싶습니다. 나는 그것을 좋은 출발점으로 생각합니다. OpenACC에 대해서도 마찬가지입니다.


0

인텔 사람들은 이해하기 쉽다고 생각합니다.

벡터화는 한 번에 단일 값에서 작동하는 알고리즘을 한 번에 값 집합에서 작동하는 것으로 변환하는 프로세스입니다 . 최신 CPU는 단일 명령이 다중 데이터 (SIMD)에 적용되는 벡터 연산을 직접 지원합니다.

예를 들어 512 비트 레지스터가있는 CPU는 16 개의 32 비트 단 정밀도 배를 보유하고 단일 계산을 수행 할 수 있습니다.

한 번에 하나의 명령을 실행하는 것보다 16 배 더 빠릅니다. 이것을 스레딩 및 멀티 코어 CPU와 결합하면 성능이 크게 향상됩니다.

링크 https://software.intel.com/en-us/articles/vectorization-a-key-tool-to-improve-performance-on-modern-cpus

Java에는 2020 년 Jdk 15에 포함되거나 2021 년 JDK 16에 늦게 포함되는 옵션이 있습니다.

https://bugs.openjdk.java.net/browse/JDK-8201271


-4

위의 두 가지 답변을 참조하십시오. 벡터화를 원하는 이유는 슈퍼 컴퓨터와 멀티 프로세서에 의해 이러한 작업을 쉽게 수행 할 수 있기 때문에 성능이 크게 향상되기 때문입니다. 단일 프로세서 컴퓨터에서는 성능이 향상되지 않습니다.


12
"단일 프로세서 컴퓨터에서는 성능 향상이 없습니다": 사실이 아닙니다. 대부분의 최신 프로세서에는 벡터화를위한 (제한된) 하드웨어 지원 (stephenyrone의 이름을 가진 SSE, Altivec 등)이있어 사용시 속도를 크게 높일 수 있습니다.
sleske

덕분에 병렬화도 그 수준에서 수행 할 수 있다는 것을 잊었습니다.
래리 와타나베
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.