2016-02-22 5 views
3

Я пытаюсь прорисовать упрощенную версию примера 4 из gcc auto-vectorize documentation. Для жизни я не могу понять, как это сделать;gcc не будет векторизовать простую петлю

typedef int aint __attribute__ ((__aligned__(16))); 
void foo1 (int n, aint * restrict px, aint *restrict qx) { 

    /* feature: support for (aligned) pointer accesses. */ 
    int *__restrict p = __builtin_assume_aligned (px, 16); 
    int *__restrict q = __builtin_assume_aligned (qx, 16); 

    while (n--){ 
    //*p++ += *q++; <- this is vectorized                                         
    p[n] += q[n]; // This isn't!                                            
    } 
} 

Я бег GCC 4.7.2 с GCC -o приложениями/craft_dbsplit.o -c -g -Wall -ggdb -O3 -msse2 -funsafe-математика-оптимизация -ffast-математическая -ftree- векторизовать -ftree-векторизатор-многословным = 5 -funsafe-петля-оптимизации -std = C99

И это отвечает:

Analyzing loop at apps/craft_dbsplit.c:388 

388: dependence distance = 0. 
388: dependence distance == 0 between *D.9363_14 and *D.9363_14 
388: dependence distance = 0. 
388: accesses have the same alignment. 
388: dependence distance modulo vf == 0 between *D.9363_14 and *D.9363_14 
388: vect_model_load_cost: unaligned supported by hardware. 
388: vect_get_data_access_cost: inside_cost = 2, outside_cost = 0. 
388: vect_model_store_cost: unaligned supported by hardware. 
388: vect_get_data_access_cost: inside_cost = 2, outside_cost = 0. 
388: Alignment of access forced using peeling. 
388: Vectorizing an unaligned access. 
388: vect_model_load_cost: aligned. 
388: vect_model_load_cost: inside_cost = 1, outside_cost = 0 . 
388: vect_model_load_cost: unaligned supported by hardware. 
388: vect_model_load_cost: inside_cost = 2, outside_cost = 0 . 
388: vect_model_simple_cost: inside_cost = 1, outside_cost = 0 . 
388: not vectorized: relevant stmt not supported: *D.9363_14 = D.9367_20; 

apps/craft_dbsplit.c:382: note: vectorized 0 loops in function. 
+4

"Я запускаю gcc 4.7.2" Возможно, вам потребуется обновить его, это довольно старый. Более новые версии вектурируют цикл. – edmz

+0

Хотя gcc встроенный вектор довольно сломан, но вы можете дать ему попробовать – user3528438

+1

Для чего это стоит: задано 'while (n -)', то '* p ++ + = * q ++;' не эквивалентно 'p [ n] + = q [n]; '. Вторая версия выполняет итерацию назад. – Lundin

ответ

1

цикл работает от высоких адресов к низким адресам. Ваш gcc обрабатывает векторные операции как работающие от низких адресов до высоких адресов и, следовательно, не понимает, что он может векторизовать. Ваша «оптимизация», создающая цикл while (n--), фактически предотвращает более значимую оптимизацию. Попробуйте

#include <stddef.h> 

void foo1 (size_t n, int *restrict px, int const *restrict qx) 
{ 
    int *restrict p = __builtin_assume_aligned(px, 16); 
    int const *restrict q = __builtin_assume_aligned(qx, 16); 
    size_t i = 0; 
    while (i < n) 
    { 
     p[i] += q[i]; 
     i++; 
    } 
} 
+0

Почему бы просто не сделать неясный цикл: 'for (size_t i = 0; i Lundin

+1

@ Lundin: Множество способов кожи кошки. – EOF

+3

Да, вы можете использовать нож с кошачьей шкурой, хорошо известный и сразу же признанный всеми кошачьями, или вы могли бы использовать что-то еще :) – Lundin

Смежные вопросы