Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
$ cat i.c
void func(int *data, int size)
{
int i;
i = 0;
while (i < size)
{
data[i] = i * 2;
i++;
}
}
$ gcc -O3 -march=native -c -fdump-tree-vect-details -ftree-vectorizer-verbose=1 i.c
Analyzing loop at i.c:6
Vectorizing loop at i.c:6
i.c:6: note: === vect_do_peeling_for_alignment ===
i.c:6: note: niters for prolog loop: MIN_EXPR <-(((unsigned int) vect_pdata.7_2 & 15) >> 2) & 3, niters.4_19>Setting upper bound of nb iterations for prologue loop to 5
i.c:6: note: === vect_update_inits_of_dr ===
i.c:6: note: === vect_do_peeling_for_loop_bound ===Setting upper bound of nb iterations for epilogue loop to 2
i.c:6: note: LOOP VECTORIZED.
i.c:1: note: vectorized 1 loops in function.
i.c:6: note: Completely unroll loop 2 times
i.c:1: note: Completely unroll loop 5 times
$ wc -l i.c.112t.vect
597 i.c.112t.vect
Analyzing loop at i.c:6
i.c:6: note: ===== analyze_loop_nest =====
i.c:6: note: === vect_analyze_loop_form ===
i.c:6: note: === get_loop_niters ===Analyzing # of iterations of loop 1
exit condition [1, + , 1](no_overflow) < size_4(D)
bounds on difference of bases: 0 ... 2147483646
result:
# of iterations (unsigned int) size_4(D) + 4294967295, bounded by 2147483646
. . .
i.c:6: note: vectorization factor = 4
i.c:6: note: === vect_analyze_data_refs_alignment ===
i.c:6: note: vect_compute_data_ref_alignment:
i.c:6: note: can't force alignment of ref: *_8
i.c:6: note: === vect_analyze_data_ref_accesses ===
i.c:6: note: === vect_prune_runtime_alias_test_list ===
i.c:6: note: === vect_enhance_data_refs_alignment ===
i.c:6: note: Unknown misalignment, is_packed = 0
i.c:6: note: vect_can_advance_ivs_p:
i.c:6: note: Analyze phi: i_14 = PHI <i_11(7), 0(4)>
. . .
i.c:6: note: === vect_update_slp_costs_according_to_vf ===cost model: prologue peel iters set to vf/2.cost model: epilogue peel iters set to vf/2 because peeling for alignment is unknown.
i.c:6: note: Cost model analysis:
Vector inside of loop cost: 4
Vector prologue cost: 18
Vector epilogue cost: 6
Scalar iteration cost: 3
Scalar outside cost: 7
Vector outside cost: 24
prologue iterations: 2
epilogue iterations: 2
Calculated minimum iters for profitability: 7
. . .
loop at i.c:8: if (ivtmp_77 < bnd.11_43)
;; Scaling loop 1 with scale 0.250000, bounding iterations to 2 from guessed 11
;; guessed iterations are now 1
Не знал, однако, с какой версии он это умеет?С тех пор, как умеет выполнять автоматическую векторизацию.
перестановок в коде программы, которые могут дать неожиданный эффект«Неожиданный эффект» — это растяжимое понятие. Компилятор же не знает, что именно вам показалось «очевидно оптимизируемым местом» для «достаточно сообразительного» компилятора.
И соль этих историй обычно заключается в том, что бравый разработчик с IDA наперевес и обложившись стандартом/мануалами по процессору/котом и чашками кофе, пытается понять, что сделал компилятор, почему компилятор сделал так, а главное, как заставить его этого НЕ делать. <...> Но в тех историях явно умные люди почему-то не использовали такие возможности компилятора, из чего я предполагаю, что их просто не было.Дело больше в том, что компилятор — это невероятно сложная программа. Подобные дампы и есть отражением того, что на самом деле происходит. Но если быть честным, то разработчиков прикладных программ это мало волнует; у них есть своя сложная программа и последнее, что им хочется, — это разбираться в ещё одной. Именно поэтому проблема «у меня не оптимизирует» чаще решается вставкой подсказок компилятору в местах, обнаруженных Идой, а не исправлением компилятора в местах, обнаруженных по таким логам. Ведь проще переписать какой-нибудь невекторизиремый цикл самому, перебрав пяток вариантов, нежели научить компилятор это делать самостоятельно.
«Неожиданный эффект» — это растяжимое понятие. Компилятор же не знает, что именно вам показалось «очевидно оптимизируемым местом» для «достаточно сообразительного» компилятора.
Дело больше в том, что компилятор — это невероятно сложная программа. Подобные дампы и есть отражением того, что на самом деле происходит.
И я имел ввиду не конкретные оптимизиции по развертке циклов в векторизации, а вообще всех перестановок в коде программы, которые могут дать неожиданный эффект.
зависимости по данным и по управлению с точки зрения скуделера не нарушаются
clang: warning: argument unused during compilation: '-Rpass=loop-vectorize'clang++ -O3 -Rpass=loop-vectorize -S test4.cpp -o /dev/null#pragma omp simd collapse(3)
for(i=...
for(j=...
for(k=...
body(i, j, k);
clang foo.c -mllvm -debug-only=loop-vectorize
LV:clang foo.c -mllvm -debug
Векторизация циклов: диагностика и контроль