【发布时间】:2016-05-14 23:59:08
【问题描述】:
我需要比较大量相似的小尺寸(最大 200x200)图像。 所以我尝试实现 SSIM(结构相似性见https://en.wikipedia.org/wiki/Structural_similarity)算法。 SSIM 需要计算两个 8 位灰度图像的协方差。 一个简单的实现如下所示:
float SigmaXY(const uint8_t * x, const uint8_t * y, size_t size, float averageX, float averageY)
{
float sum = 0;
for(size_t i = 0; i < size; ++i)
sum += (x[i] - averageX) * (y[i] - averageY);
return sum / size;
}
但它的性能很差。 所以我希望通过使用 SIMD 或 CUDA 来改进它(听说可以做到)。 不幸的是,我没有这样做的经验。 它会是什么样子?我必须去哪里?
【问题讨论】:
-
您是否允许您的编译器积极优化(例如,
-funsafe-math-optimizations或-Ofast在 gcc 上)?如果你不这样做,编译器就不能对代码做很多事情,因为浮点数学不是关联的,它不能向量化。 -
好点:
-O3 -ffast-math -march=haswell,clang auto-vectorizes the OP's scalar code a lot like Ermlg's earlier answer。它使用pmovzx加载和 FMA,并利用 AVX2 来使用 256b 向量。该godbolt链接有一些我正在努力的改进,比如更有效的水平总和。
标签: c++ image-processing optimization sse simd