Я работаю над написанием теста OpenCL на C. В настоящее время он измеряет производительность слитного умножения-накопления как устройства CL, так и системного процессора, используя код C. Затем результаты проходят перекрестную проверку на точность.
Я написал собственный код, чтобы воспользоваться автоматическим векторизатором GCC, и он работает. Однако я заметил, что GCC ведет себя странно с флагом «-march = native».
Это мой цикл:
#define BUFFER_SIZE_SQRT 4096
#define SQUARE(n) (n * n)
#define ROUNDS_PER_ITERATION 48
static float* cpu_result_matrix(const float* a, const float* b, const float* c)
{
float* res = aligned_alloc(16, SQUARE(BUFFER_SIZE_SQRT) * sizeof(float));
const unsigned buff_size = SQUARE(BUFFER_SIZE_SQRT);
const unsigned round_cnt = ROUNDS_PER_ITERATION;
float lres;
for(unsigned i = 0; i < buff_size; i++)
{
lres = 0;
for(unsigned j = 0; j < round_cnt; j++)
{
lres += a[i] * ((b[i] * c[i]) + b[i]);
lres += b[i] * ((c[i] * a[i]) + c[i]);
lres += c[i] * ((a[i] * b[i]) + a[i]);
}
res[i] = lres;
}
return res;
}
Когда я компилирую с помощью "-march = native -Ofast" в системе Broadwell, я получаю хороший векторизованный код AVX.
.L19:
vmovups ymm0, YMMWORD PTR [rcx+rdx]
mov eax, 48
vmovups ymm2, YMMWORD PTR [rdi+rdx]
vaddps ymm1, ymm0, ymm5
vmovups ymm3, YMMWORD PTR [rsi+rdx]
vaddps ymm4, ymm2, ymm5
vmulps ymm1, ymm1, ymm2
vfmadd132ps ymm4, ymm1, ymm0
vaddps ymm1, ymm3, ymm5
vmulps ymm0, ymm2, ymm0
vmulps ymm0, ymm0, ymm1
vfmadd132ps ymm4, ymm0, ymm3
vmovaps ymm1, ymm4
vxorps xmm0, xmm0, xmm0
.p2align 4,,10
.p2align 3
Компиляция с теми же флагами в системе Piledriver испускает инструкции SSE2, но не инструкции AVX, даже если архитектура поддерживает это. (Я поясню свой заголовок, сказав, что Broadwell и Piledriver не похожи друг на друга, но оба они поддерживают одинаковые расширения набора векторных инструкций, поэтому генерируемый код должен быть похожим.)
.L19:
mov eax, 48
movups xmm0, XMMWORD PTR [rcx+rdx]
movups xmm2, XMMWORD PTR [r13+0+rdx]
movaps xmm4, xmm0
movaps xmm1, xmm2
movups xmm3, XMMWORD PTR [rsi+rdx]
addps xmm4, xmm5
addps xmm1, xmm5
mulps xmm4, xmm2
mulps xmm1, xmm0
mulps xmm0, xmm2
addps xmm1, xmm4
movaps xmm4, xmm1
mulps xmm4, xmm3
addps xmm3, xmm5
mulps xmm0, xmm3
addps xmm4, xmm0
pxor xmm0, xmm0
movaps xmm1, xmm4
.p2align 4,,10
.p2align 3
Я даже могу скомпилировать весь проект с помощью -march = broadwell и запустить его в системе Piledriver, и он работает с ~ 100% приростом производительности.
Я компилирую с GCC 5.1.0, и "-ftree-vectorizer-verbose", похоже, больше не работает, поэтому поведение компилятора довольно непрозрачно. Я не нашел никакой информации об устаревшем флаге, поэтому я не уверен, почему он больше не работает, и мне действительно хотелось бы выяснить, что делает GCC.
Весь проект находится здесь: https://github.com/jakogut/clperf/tree/v0.1
-v
увидеть, до чего-march=native
расширяется? См.-fopt-info-...
в документе. - person Marc Glisse   schedule 18.06.2015-ftree-vectorizer-verbose
был заменен на-fopt-info-vec-*
- person Ross Ridge   schedule 18.06.2015