我有一部分代码被称为很多次。我怎样才能加快速度?
#define SUM_(p0, p1, p2, p3, offset)
((p0)[offset] - (p1)[offset] - (p2)[offset] + (p3)[offset])
inline int Calc::compute( int offset ) const
{
int b = SUM( p[5], p[6], p[9], p[10], offset );
int a1 = SUM(...);
int a2 = SUM(...);
....
return (uchar)(((a1 >= b) << 7) |
((a2 >= b) << 6) |
((a3 >= b) << 5) |
((a4 >= b) << 4) |
((a5 >= b) << 3) |
((a6 >= b) << 2) |
((a7 >= b) << 1) |
(a8 >= b));
}
谢谢。
答案 0 :(得分:0)
我在这里看到了3个可能的机会:
将p0,p1,p2和p3数据连续打包在内存中(因此基本上连续在数组中)以防止缓存未命中:
#define SUM_(array, offset)
(array[offset] - array[offset + 1] - array[offset + 2] + array[offset + 3])
....
//make sure pArray contains all the p0, p1, ... values.
int a1 = SUM(pArray, offset);
用if结构替换bitshift运算符,或者如果(a1&gt; = b)依此类推,则使用静态文字。无论如何,这些值都是静态的:
uint8_t bitmask = 0;
if(a1 >= b)
bitmask |= 0x80;
if(a2 >= b)
bitmask |= 0x40;
...
尝试确保使用SIMD说明。这涉及转储程序集并查看是否正在生成这些指令。
编辑:对以下评论的反应:
为了防止缓存未命中,一切都围绕以可预测的方式访问您的数据。原始代码的一个问题是您使用p变量解决了偏移量。
所以你有类似的东西:
int b = SUM( p[5], p[6], p[9], p[10], _offset );
int a1 = SUM( p[0], p[1], p[4], p[5], _offset );
int a2 = SUM( p[1], p[2], p[5], p[6], _offset );
您可以按照使用顺序创建一个包含这些值的数组。
所以我尝试在某个偏移处创建一个看起来像这样的数组:
p[5], p[6], p[9], p[10], p[0], p[1], p[4], p[5], p[1], p[2], p[5], p[6]
现在你可以像这样定义你的sum函数:
#define SUM_(array, offset, calculationOffset)
(array[offset + calculationOffset * 4] - array[offset + calculationOffset * 4 + 1]
- array[offset + calculationOffset * 4 + 2] + array[offset + calculationOffset * 4 + 3])
您的电话可以转换为:
int b = SUM(pArray, offset, 0);
int a1 = SUM(pArray, offset, 1);
int a2 = SUM(pArray, offset, 2);
这只有一个问题:如果你必须创建数组并在每个函数调用中复制所有数据,这可能会消除我们所做的任何好处,但你可能能够构造这种类型的使用此函数之前的数组并将其作为参数传递。
答案 1 :(得分:0)
仍有可能改变/改进算法本身。除非你使用的算法是已知的(我的意思是使用你所显示的代码的算法),否则我们无法帮助你。
如果使用的变量有任何已知属性及其值,则可以提供改进的空间。
我不知道uchar
的演员表是否会影响表演。你为什么需要这个?我认为应该更改,因为您要添加int
并返回int
。但是你需要了解性能,看看例如使用& 0xff
是否会提供更好的性能。
此外,你应该尝试通过一个简单的加法替换bit-oring-operators(“|”)时产生的差异(在这种情况下应该工作相同,因为每个summand都有一个唯一的位设置为1)
然后尝试将(a1 >= b) << 7)
更改为(a1 >= b) ? 128 : 0)
等的效果
以上所有可能会影响性能,也可能不会影响性能,您必须使用您使用的编译器来衡量效果。
但最重要的是:如果分析所有这些图像的问题是总时间,您应该考虑同时处理不同的图像(如果您在具有足够RAM的多处理器机器上)。您有几种选择:
平行处理单个图片的代码(使用类似OpenMP的内容)
每个图像使用一个线程(恕我直言更容易,我希望整体吞吐量比1更好。)
将并发性移动到启动程序的位置(即脚本)。