Я не понимаю, почему такой код не векторизаций с GCC 4.4.6НКУ авто-векторизация (необработанные данные ссылок)
int MyFunc(const float *pfTab, float *pfResult, int iSize, int iIndex)
{
for (int i = 0; i < iSize; i++)
pfResult[i] = pfResult[i] + pfTab[iIndex];
}
note: not vectorized: unhandled data-ref
Однако, если я пишу следующий код
int MyFunc(const float *pfTab, float *pfResult, int iSize, int iIndex)
{
float fTab = pfTab[iIndex];
for (int i = 0; i < iSize; i++)
pfResult[i] = pfResult[i] + fTab;
}
НКУ преуспевает автоматического Vectorize этот цикл
если добавить директиву OMP
int MyFunc(const float *pfTab, float *pfResult, int iSize, int iIndex)
{
float fTab = pfTab[iIndex];
#pragma omp parallel for
for (int i = 0; i < iSize; i++)
pfResult[i] = pfResult[i] + fTab;
}
У меня есть следующая погрешность: нет необработанных данных-ref
Не могли бы вы помочь мне, почему первый код и третий код не авто-векторизованы?
Второго вопрос: математика операнд, кажется, не векторизации (ехр, журнал, и т.д. ...), этот код, например
for (int i = 0; i < iSize; i++)
pfResult[i] = exp(pfResult[i]);
не векторизации. Это из-за моей версии gcc?
Edit: с новой версией GCC 4.8.1 и OpenMP 2011 (эхо | касты -fopenmp -dM | Grep -i открыть) я имею следующую ошибку для всех видов петли даже в основном
for (iGID = 0; iGID < iSize; iGID++)
{
pfResult[iGID] = fValue;
}
note: not consecutive access *_144 = 5.0e-1;
note: Failed to SLP the basic block.
note: not vectorized: failed to find SLP opportunities in basic block.
Edit2:
#include<stdio.h>
#include<sys/time.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include <omp.h>
int main()
{
int szGlobalWorkSize = 131072;
int iGID = 0;
int j = 0;
omp_set_dynamic(0);
// warmup
#if WARMUP
#pragma omp parallel
{
#pragma omp master
{
printf("%d threads\n", omp_get_num_threads());
}
}
#endif
printf("Pagesize=%d\n", getpagesize());
float *pfResult = (float *)malloc(szGlobalWorkSize * 100* sizeof(float));
float fValue = 0.5f;
struct timeval tim;
gettimeofday(&tim, NULL);
double tLaunch1=tim.tv_sec+(tim.tv_usec/1000000.0);
double time = omp_get_wtime();
int iChunk = getpagesize();
int iSize = ((int)szGlobalWorkSize * 100)/iChunk;
//#pragma omp parallel for
for (iGID = 0; iGID < iSize; iGID++)
{
pfResult[iGID] = fValue;
}
time = omp_get_wtime() - time;
gettimeofday(&tim, NULL);
double tLaunch2=tim.tv_sec+(tim.tv_usec/1000000.0);
printf("%.6lf Time1\n", tLaunch2-tLaunch1);
printf("%.6lf Time2\n", time);
}
результат с
#define _OPENMP 201107
gcc (GCC) 4.8.2 20140120 (Red Hat 4.8.2-15)
gcc -march=native -fopenmp -O3 -ftree-vectorizer-verbose=2 test.c -lm
много
note: Failed to SLP the basic block.
note: not vectorized: failed to find SLP opportunities in basic block.
and note: not consecutive access *_144 = 5.0e-1;
Благодарности
Первым делом стоит попробовать более новую версию gcc. Тогда поймите, что без «ограничения» векторизация может быть неправильной. И добавьте -ffast-math, потому что компилятор в противном случае испугался. Для exp и log я уверен, что видел связанные вопросы о SO. В принципе, вам понадобится библиотека, которая предоставляет векторные версии exp и log, так что gcc может генерировать вызовы к ним. –
Scratch мой предыдущий комментарий, почему вы не используете 'i' в своих циклах ??? –
спасибо большое Я уже пробовал с '__restrict__' и const, и результат тот же Я попробую с более новой версией gcc извините за цикл typo – parisjohn