Я работаю над написанием теста OpenCL в C. В настоящее время он измеряет скользящую совокупную производительность как CL-устройства, так и системного процессора с использованием кода C. Затем результаты проверяются на точность.
Я написал собственный код, чтобы использовать GCC auto vectorizer, и он работает. Тем не менее, я заметил, что 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