GCC: 유사한 두 루프 사이의 벡터화 차이
gcc -O3
되지 않는 이유는 무엇입니까?:,가(으로) 입니까?
#define SIZE (65536)
int a[SIZE], b[SIZE], c[SIZE];
int foo () {
int i, j;
for (i=0; i<SIZE; i++){
for (j=i; j<SIZE; j++) {
a[i] = b[i] > c[j] ? b[i] : c[j];
}
}
return a[0];
}
다음 것이 그러할 때?
#define SIZE (65536)
int a[SIZE], b[SIZE], c[SIZE];
int foov () {
int i, j;
for (i=0; i<SIZE; i++){
for (j=i; j<SIZE; j++) {
a[i] += b[i] > c[j] ? b[i] : c[j];
}
}
return a[0];
}
유일한 차이는 내부 루프에서 식의 결과가 a[i]에 할당되는지 아니면 a[i]에 추가되는지 여부입니다.
-ftree-vectorizer-verbose=6
는 첫 번째(비 vector라이징) 루프에 대해 다음과 같은 출력을 제공합니다.
v.c:8: note: not vectorized: inner-loop count not invariant.
v.c:9: note: Unknown alignment for access: c
v.c:9: note: Alignment of access forced using peeling.
v.c:9: note: not vectorized: live stmt not supported: D.2700_5 = c[j_20];
v.c:5: note: vectorized 0 loops in function.
벡터화하는 루프에 대한 동일한 출력은 다음과 같습니다.
v.c:8: note: not vectorized: inner-loop count not invariant.
v.c:9: note: Unknown alignment for access: c
v.c:9: note: Alignment of access forced using peeling.
v.c:9: note: vect_model_load_cost: aligned.
v.c:9: note: vect_model_load_cost: inside_cost = 1, outside_cost = 0 .
v.c:9: note: vect_model_simple_cost: inside_cost = 1, outside_cost = 1 .
v.c:9: note: vect_model_reduction_cost: inside_cost = 1, outside_cost = 6 .
v.c:9: note: cost model: prologue peel iters set to vf/2.
v.c:9: note: cost model: epilogue peel iters set to vf/2 because peeling for alignment is unknown .
v.c:9: note: Cost model analysis:
Vector inside of loop cost: 3
Vector outside of loop cost: 27
Scalar iteration cost: 3
Scalar outside cost: 7
prologue iterations: 2
epilogue iterations: 2
Calculated minimum iters for profitability: 8
v.c:9: note: Profitability threshold = 7
v.c:9: note: Profitability threshold is 7 loop iterations.
v.c:9: note: LOOP VECTORIZED.
v.c:5: note: vectorized 1 loops in function.
첫 번째 경우: 코드가 동일한 메모리 위치를 덮어씁니다.a[i]
한번씩 반복해서 이는 않기 에 본질적으로 합니다.이는 루프 반복이 독립적이지 않기 때문에 본질적으로 루프를 순차화합니다.
(실제로는 최종 반복만 필요합니다.따라서 내부 루프 전체를 제거할 수 있습니다.)
두 번째 경우: GCC는 루프를 축소 연산으로 인식합니다. 이를 위해 벡터화할 수 있는 특수한 경우 처리가 있습니다.
컴파일러 벡터화는 종종 일종의 "패턴 매칭"으로 구현됩니다.컴파일러는 코드가 벡터화할 수 있는 특정 패턴에 맞는지 확인하기 위해 코드를 분석합니다.만약 그렇게 된다면, 벡터화 됩니다.그렇지 않으면 그렇지 않습니다.
이것은 첫 번째 루프가 GCC가 처리할 수 있는 미리 코딩된 패턴에 맞지 않는 코너 케이스인 것 같습니다.그러나 두 번째 경우는 "벡터화 가능한 감소" 패턴에 적합합니다.
은 의입니다 GCC "not vectorized: live stmt not supported: "
메시지:
http://svn.open64.net/svnroot/open64/trunk/osprey-gcc-4.2.0/gcc/tree-vect-analyze.c
if (STMT_VINFO_LIVE_P (stmt_info))
{
ok = vectorizable_reduction (stmt, NULL, NULL);
if (ok)
need_to_vectorize = true;
else
ok = vectorizable_live_operation (stmt, NULL, NULL);
if (!ok)
{
if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
{
fprintf (vect_dump,
"not vectorized: live stmt not supported: ");
print_generic_expr (vect_dump, stmt, TDF_SLIM);
}
return false;
}
}
대사만 보면 다음과 같습니다.
vectorizable_reduction (stmt, NULL, NULL);
GCC가 "벡터화 가능한 감소" 패턴과 일치하는지 확인 중인 것은 분명합니다.
GCC 벡터라이저는 아마도 첫 번째 루프를 벡터화하기에 충분히 똑똑하지 않을 것입니다.다이기 가 더 .다a + 0 == a
해 보세요.SIZE==4
:
0 1 2 3 i
0 X
1 X X
2 X X X
3 X X X X
j
X
는다의 .i
그리고.j
a
에 할당되거나 증가됩니다.우,다의 결과를 할 수 .b[i] > c[j] ? b[i] : c[j]
예를 면 j==1
그리고.i==0..4
겁니다.D
0. 0 만 됩니다.D[2..3]
합니다.a[0..3]
더 과제의 경우에는 조금 더 까다롭습니다.다 0는 안 됩니다.D[2..3]
0, 0A[0..1]
그 다음에야 결과를 합칠 수 있습니다.여기서 벡터라이저가 고장난 것 같습니다.
첫번째 루프는 다음과 같습니다.
#define SIZE (65536)
int a[SIZE], b[SIZE], c[SIZE];
int foo () {
int i, j;
for (i=0; i<SIZE; i++){
a[i] = b[i] > c[SIZE - 1] ? b[i] : c[SIZE - 1];
}
return a[0];
}
원래 표현의 문제는 그것이 정말 그렇게 말이 되지 않는다는 것입니다. 그래서 gcc가 벡터화하지 못하는 것이 그리 놀랍지 않습니다.
첫번째 것은 그저 a[]를 여러번 바꾸는 것입니다.두 번째 값은 매번 a[]의 마지막 값을 사용합니다(일시적이 아님).
패치 버전까지 "volatile" 변수를 사용하여 벡터화할 수 있습니다.
사용하다
int * c=malloc(sizeof(int));
정렬되도록 하기 위해,
v.c:9: note: Unknown alignment for access: c
band a와는 다른 저장 영역을 가진 "c"를 보여줍니다.
나는 "벡터화"된 "모브랩스"와 같은 명령을 가정합니다 (SSE-AVX 명령 목록에서).
여기: http://gcc.gnu.org/projects/tree-ssa/vectorization.html#using
6번째와 7번째 예시는 비슷한 어려움을 보여줍니다.
언급URL : https://stackoverflow.com/questions/12096599/gcc-vectorization-difference-between-two-similar-loops
'programing' 카테고리의 다른 글
Oracle 생성 트리거 오류(나쁜 바인딩 변수) (0) | 2023.09.21 |
---|---|
jquery에서 드롭다운 상자 사용/사용 안 함 (0) | 2023.09.21 |
Mysql select distinct (0) | 2023.09.21 |
int 배열 초기화 (0) | 2023.09.16 |
Swift: 인덱스에서 문자열 배열 바꾸기 (0) | 2023.09.16 |