나는 스칼라 행렬 덧셈 커널을 구현했다.스칼라 매트릭스 추가에 addss 대신 vaddss를 사용하면 어떤 이점이 있습니까?
gcc -O2 msse4.2
: 다음
#include <stdio.h>
#include <time.h>
//#include <x86intrin.h>
//loops and iterations:
#define N 128
#define M N
#define NUM_LOOP 1000000
float __attribute__((aligned(32))) A[N][M],
__attribute__((aligned(32))) B[N][M],
__attribute__((aligned(32))) C[N][M];
int main()
{
int w=0, i, j;
struct timespec tStart, tEnd;//used to record the processiing time
double tTotal , tBest=10000;//minimum of toltal time will asign to the best time
do{
clock_gettime(CLOCK_MONOTONIC,&tStart);
for(i=0;i<N;i++){
for(j=0;j<M;j++){
C[i][j]= A[i][j] + B[i][j];
}
}
clock_gettime(CLOCK_MONOTONIC,&tEnd);
tTotal = (tEnd.tv_sec - tStart.tv_sec);
tTotal += (tEnd.tv_nsec - tStart.tv_nsec)/1000000000.0;
if(tTotal<tBest)
tBest=tTotal;
} while(w++ < NUM_LOOP);
printf(" The best time: %lf sec in %d repetition for %dX%d matrix\n",tBest,w, N, M);
return 0;
}
, I는 다른 컴파일러 플래그와 내부 루프의 조립 출력 프로그램을 컴파일 한이며, 가장 시간 : 128X128위한 0.000024 초에서 406,490 반복 매트릭스
movss xmm1, DWORD PTR A[rcx+rax]
addss xmm1, DWORD PTR B[rcx+rax]
movss DWORD PTR C[rcx+rax], xmm1
gcc -O2 -mavx
: 최고의 시간 : 0.000009 초에서 1,000,001 반복
AVX 버전 gcc -O2 -mavx
:
__m256 vec256;
for(i=0;i<N;i++){
for(j=0;j<M;j+=8){
vec256 = _mm256_add_ps(_mm256_load_ps(&A[i+1][j]) , _mm256_load_ps(&B[i+1][j]));
_mm256_store_ps(&C[i+1][j], vec256);
}
}
SSE 버전 gcc -O2 -sse4.2
::
__m128 vec128;
for(i=0;i<N;i++){
for(j=0;j<M;j+=4){
vec128= _mm_add_ps(_mm_load_ps(&A[i][j]) , _mm_load_ps(&B[i][j]));
_mm_store_ps(&C[i][j], vec128);
}
}
스칼라 프로그램에서이 msse4.2
이상 -mavx
의 속도 향상은 2.7 배이다. 나는 ISA를 효율적으로 개선 한 avx
을 알고 있으며 이러한 개선으로 인해있을 수 있습니다. 그러나 AVX
및 SSE
모두에 대해 내장 프로그램에서 프로그램을 구현하면 속도가 3 배 빨라졌습니다. 문제는 AVX 스칼라가 SSE보다 2.7 배 빨라서 벡터화 할 때 속도가 3 배 (매트릭스 크기는 128x128)입니다. 스칼라 모드에서 AVX 및 SSE를 사용하면 2.7 배의 속도 향상이 가능합니다. SSE의 네 요소에 비해 AVX에서 여덟 요소를 처리하기 때문에 벡터화 된 방법이 더 좋아야합니다. perf stat
이보고 된대로 모든 프로그램의 캐시 누락이 4.5 % 미만입니다. 사용
gcc -O2
, linux mint
, skylake
UPDATE : 간단하게는, 스칼라 AVX는이 벡터화하는 동안에 스칼라 SSE하지만 AVX-256은 SSE-128에 비해 단지 3 배 더 빠른 것보다 2.7 배 빠릅니다. 파이프 라이닝 때문일 수도 있습니다. 스칼라에는 벡터화 된 모드에서 사용할 수없는 3 vec-ALU
이 있습니다. 나는 사과 대신에 사과와 사과를 사과와 비교해 볼 수도 있는데, 그 이유를 이해하지 못할 수도 있습니다.
제목 질문에 답변하려면 (본문의 마지막 부분을 완전히 파싱 할 수 없음) : [GCC는 -O1에서 컴파일 할 때만 말한 내용을 수행합니다] (https://godbolt.org/g/T4xnCU). AVX가있는 시스템을 대상으로 할 때 [기존 SSE 지침의 VEX 버전을 사용하는 것이 좋습니다] (https://software.intel.com/sites/default/files/m/d/4/1/d/8) /11MC12_Avoiding_2BAVX-SSE_2BTransition_2BPenalties_2Brh_2Bfinal.pdf). –
@MargaretBloom, no gcc -O2' 나는 질문에 덧붙였다. 타겟팅은 정상이지만 AVX-128이 아닌 순수한'AVX'와'SSE'를 AVX-256이 아닌 AVX-128과 비교하고 있습니다. – Martin
@MargaretBloom, 벡터화는'-O3'에 의해 가능하지만'-O2'가 아닌'-ftree-loop-vectorize'에 의해 가능합니다. –