【发布时间】:2015-09-12 05:55:50
【问题描述】:
这个问题只是为了尝试对循环向量化有更多的了解,尤其是使用 OpenMP4。下面给出的代码生成“size”随机样本,然后从这些样本中,我们从位置“qpos”中提取“qsize”样本的“q”。然后程序在“samples”数组中找到“q”的位置。这是代码:
#include <float.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <mm_malloc.h>
// SIMD size in floats, assuming 1 float = 4 bytes
#define VEC_SIZE 8
#define ALIGN (VEC_SIZE*sizeof(float))
int main(int argc, char *argv[])
{
if (argc!=4)
{
printf("Usage: %s <size> <qsize> <qpos>",argv[0]);
exit(1);
}
int size = atoi(argv[1]);
int qsize = atoi(argv[2]);
int qpos = atoi(argv[3]);
assert(qsize < size);
assert((qpos < size - qsize) && (qpos >= 0));
float *samples;
float *q;
samples = (float *) malloc(size*sizeof(float));
q = (float *) _mm_malloc(size*sizeof(float),ALIGN);
// Initialization
// - Randomly filling the samples
samples[0] = 0.0;
for (int i = 1 ; i < size; i++) //LOOP1
samples[i] = samples[i-1] + rand()/((float)RAND_MAX) - 0.5;
// - Getting q from the samples
#pragma omp simd aligned(q:ALIGN)
for (int i = 0; i < qsize; i++) //LOOP2
q[i] = samples[qpos+i];
// Finding the best match (since q is taken form the samples it self
// the position of the best match must be qpos)
float best_dist = FLT_MAX;
int pos = -1;
for (int i = 0; i < size - qsize; i++)//LOOP 3
{
float dist = 0;
#pragma omp simd aligned(q:ALIGN) reduction(+:dist)
for (int j = 0; j < qsize; j++)//LOOP4
dist += (q[j] - samples[i+j]) * (q[j] - samples[i+j]);
if (dist < best_dist)
{
best_dist = dist;
pos = i;
}
}
assert(pos==qpos);
printf("Done!\n");
free(samples);
_mm_free(q);
}
我正在使用 icc 15.0.0 和 gcc 4.9.2 使用以下命令进行编译:
icc vec-test.c -o icc-vec-test -std=c11 -qopt-report=3 -qopt-report-phase=vec -qopt-report-file=icc.vec -O3 -xHost -fopenmp
gcc vec-test.c -o gcc-vec-test -std=c11 -fopt-info-vec-missed-optimized=gcc.vec -O3 -march=native -fopenmp
'q' 使用 _mm_malloc() 对齐。对“样本”做同样的事情是没有意义的,因为最内层循环(LOOP4)总是会访问它的未对齐元素。
gcc 和 icc 都报告了 LOOP4 的矢量化(实际上,如果我们省略了 '#pragma omp simd',icc 会设法自动矢量化循环,而 gcc 拒绝这样做,但这只是一个额外的观察)。从矢量化报告看来,没有一个编译器生成剥离循环。我的问题:
1) 编译器如何处理“样本”未对齐的事实?
2) 这会对性能产生多大影响?
3) icc 对 LOOP2 进行矢量化没有问题。但是 gcc 不能:“注意:未矢量化:基本块中没有足够的数据引用”。有什么想法吗?
谢谢!
【问题讨论】:
-
对齐不再像以前那么重要了。现代处理器处理未对齐访问的速度几乎与对齐访问一样快。
-
为什么要对齐呢?如果您想要最大的性能,我想说对齐仍然很重要。
-
我只是说编译器无论如何都会向量化,即使它没有对齐。 (对于最近的处理器)他们不会特意检查或特殊情况进行对齐。仅仅是因为未对齐的开销可能小于分支和特殊情况处理的开销。
-
@Mystical:好的,同意:-)
标签: c openmp vectorization