extern inline double getColorPercentage(uint8_t *pixel, uint8_t *pixel2) {
//pixel 1 is 255, 255, 255
//pixel 2 is 0, 0, 0
//match is 0
//pixel 1 and 2 is 255, 255, 255
//match is 1.0
return (255-fabs(pixel[2] - pixel2[2])) * (255-fabs(pixel[1] - pixel2[1])) * (255-fabs(pixel[0] - pixel2[0])) /16581375.0;
}
我写了这个函数并试图优化它,并希望它可以进一步优化。我经常使用它,有人知道如何让它更高效吗?
答案 0 :(得分:9)
您正在进行大量不必要的int
到float
次转化。也可以将常数除以转换为乘法。这是一个可能更有效的版本:
inline double getColorPercentage(const uint8_t *pixel, const uint8_t *pixel2)
{
const double scale = 1.0 / (255.0 * 255.0 * 255.0); // compile-time constant
int m0 = 255 - abs(pixel[0] - pixel2[0]); // NB: use std::abs rather than fabs
int m1 = 255 - abs(pixel[1] - pixel2[1]); // and keep all of this part
int m2 = 255 - abs(pixel[2] - pixel2[2]); // in the integer domain
int m = m0 * m1 * m2;
return (double)m * scale;
}
与往常一样,您应该仔细地对原始版本和任何优化版本进行基准测试和分析,并注意使用一个编译器和目标平台进行的优化可能对另一个没有用。
答案 1 :(得分:3)
首先,我建议您使用std::abs()
代替std::fabs()
,因为您处理的uint8_t
不是浮点类型。如果仍然没有给你足够的表现,你可以试试这个:
extern inline double getColorPercentage(uint8_t *pixel1, uint8_t *pixel2)
{
int a = 255 - (pixel1[2] > pixel2[2] ? pixel1[2] - pixel2[2] : pixel2[2] - pixel1[2]);
int b = 255 - (pixel1[1] > pixel2[1] ? pixel1[1] - pixel2[1] : pixel2[1] - pixel1[1]);
int c = 255 - (pixel1[0] > pixel2[0] ? pixel1[0] - pixel2[0] : pixel2[0] - pixel1[0]);
return (a * b * c) / 16581375.0;
}
始终确保您在发布版本中进行优化并进行编译。
答案 2 :(得分:0)
除了其他答案,您可能还想检查计算是否为矢量化。请参阅this my answer;我甚至可以想象,只有你的情况可以有一个单独的内在。
事实上,在你的特定函数中,减法/乘法“循环”可以被矢量化,但是如果你从某个循环调用你的函数(我假设你这样做,否则为什么它是瓶颈?),那么可能会向量化外环将证明更有效。