Disclamer:我是一名SIMD新手,但我对OpenCV非常了解。
假设我有基本的OpenCV代码。
float *apt = __mm_alloc(sizeof(float)*m*n, 32);
float *bpt = __mm_alloc(sizeof(float)*m*n, 32);
float *xpt = __mm_alloc(sizeof(float)*m*n, 32);
cv::Mat1f a = cv::Mat(n, m, apt);
cv::Mat1f b = cv::Mat(m, n, bpt);
cv::Mat1f x = cv::Mat(n, n, xpt);
x = a+b;
现在,让我们假设我想在AVX2甚至AVX-512机器上使用上面的代码。将数据32对齐可能对性能有很大好处。上述数据不应对齐。我几乎可以肯定,因为在英特尔编译器生成的优化报告文件中,它说数据是未对齐的,但我可能是错的。
那么如果我分配32个对齐的指针并将它们用于上述操作呢?类似的东西:
cv::Mat
我在上面的代码中看到了三个与我有关的问题:
cv::Mat
中的矩阵乘法会返回一个新的__mm_malloc
对象,遗憾的是,该对象不会对齐。 __mm_free
时,我们应该使用cv::Mat
。但是,free
是"有点"聪明的指针,所以他们被重新分配和取消分配在幕后,可能会调用一些delete
或//do the code above
float *aptr = a.ptr<float>(0);
float *bptr = b.ptr<float>(0);
float *xptr = c.ptr<float>(0);
for(int i=0; i<n ; i++)
for(int j=0; j<m; j++)
xptr[i*m+j] = a[i*m+j] + b[i*m+j];
函数。为了克服问题1,在数据对齐可以提高性能的非常关键的代码段中,我可以返回指针并使用指针进行求和操作。类似的东西:
icpc
但同样,我害怕我重新发明轮子。请注意,这是一个玩具示例,使其成为MCV,我的实际代码比这复杂得多,编译器优化可能并不明显。
我使用INTEL_OPT=-O3 -ipo -simd -xCORE-AVX2 -parallel -qopenmp -fargument-noalias -ansi-alias -no-prec-div -fp-model fast=2 -fma -align -finline-functions
INTEL_PROFILE=-g -qopt-report=5 -Bdynamic -shared-intel -debug inline-debug-info -qopenmp-link dynamic -parallel-source-info=2 -ldl
和以下标志编译我的代码:
{{1}}