我正在进行一些图像处理,借助向量化技术获得了好处。我有一个可以向量化的函数,但是我无法说服编译器输入和输出缓冲区没有重叠,因此不需要进行别名检查。我应该能够使用__restrict__
来实现这一点,但如果在作为函数参数到达时未将缓冲区定义为__restrict__
,就无法让编译器确信我绝对确定两个缓冲区永远不会重叠。
这是这个函数:
__attribute__((optimize("tree-vectorize","tree-vectorizer-verbose=6")))
void threshold(const cv::Mat& inputRoi, cv::Mat& outputRoi, const unsigned char th) {
const int height = inputRoi.rows;
const int width = inputRoi.cols;
for (int j = 0; j < height; j++) {
const uint8_t* __restrict in = (const uint8_t* __restrict) inputRoi.ptr(j);
uint8_t* __restrict out = (uint8_t* __restrict) outputRoi.ptr(j);
for (int i = 0; i < width; i++) {
out[i] = (in[i] < valueTh) ? 255 : 0;
}
}
}
唯一的方法是将内部循环放在一个单独的函数中,并在其中将指针定义为__restrict__
参数,以使编译器不执行别名检查。如果我将这个内部函数声明为内联的,那么别名检查又会被激活。
您还可以通过这个例子看到效果,我认为它是一致的:http://goo.gl/7HK5p7
(注意:我知道可能有更好的编写相同函数的方法,但在这种情况下,我只是试图了解如何避免别名检查)
编辑:
问题已经解决!(请参见下面的答案)
使用gcc 4.9.2,这里是完整的示例。请注意,在超出使用-ftree-vectorizer-verbose=N
之后,使用编译器标志-fopt-info-vec-optimized
。
因此,对于gcc,请使用#pragma GCC ivdep
并享受! :)
in != out
对编译器来说绝对不足够的信息:缓冲区可能会_部分_重叠。 - Antonio