Я пытаюсь улучшить производительность от this кода, векторизаций этой функции:Является ли это хорошей практикой для векторизации?
inline float calcHaarPattern(const int* origin, const SurfHF* f, int n)
{
double d = 0;
for(int k = 0; k < n; k++)
d += (origin[f[k].p0] + origin[f[k].p3] - origin[f[k].p1] - origin[f[k].p2])*f[k].w;
return (float)d;
}
Из моего знания, вы можете векторизацию петли, которые включают в себя точно один математической операции. В приведенном выше коде мы имеем 5 математических операций, поэтому (используя OMP):
#pragma omp simd
for(int k = 0; k < n; k++)
d += (origin[f[k].p0] + origin[f[k].p3] - origin[f[k].p1] - origin[f[k].p2])*f[k].w;
Не собираюсь работать. Однако я думал, что если перерыв цикла выше в несколько циклов с помощью одной математической операции является хорошей практикой для векторизации? Итоговый код будет:
double p0[n], p3[n], p1[n], p2[n];
#pragma omp simd
for(int k = 0; k < n; k++)
p0[k] = origin[f[k].p0]*f[k].w;
#pragma omp simd
for(int k = 0; k < n; k++)
p3[k] = origin[f[k].p3]*f[k].w;
#pragma omp simd
for(int k = 0; k < n; k++)
p1[k] = origin[f[k].p1]*f[k].w;
#pragma omp simd
for(int k = 0; k < n; k++)
p2[k] = origin[f[k].p2]*f[k].w;
#pragma omp simd
for(int k = 0; k < n; k++)
d += p0[k];
#pragma omp simd
for(int k = 0; k < n; k++)
d -= p1[k];
#pragma omp simd
for(int k = 0; k < n; k++)
d -= p2[k];
#pragma omp simd
for(int k = 0; k < n; k++)
d += p3[k];
Это хорошее решение, или лучше? Современные компиляторы (скажем, gcc
) собираются сделать это (или лучше) вроде оптимизаций (например, включив -O3
) сами (так что на самом деле нет выигрыша в производительности)?
, как вы вводите некоторые неконстантные переменные, это, вероятно, будет медленнее. – felix
@felix Ehm [nope] (http://stackoverflow.com/questions/6313730/does-const-correctness-give-the-compiler-more-room-for-optimization) – justHelloWorld