ncR*_*ert 6 c++ algorithm computer-vision
我一直在使用openCV做一些块匹配,我注意到它的平方差异代码的总和与这样的直接for循环相比非常快:
int SSD = 0;
for(int i =0; i < arraySize; i++)
SSD += (array1[i] - array2[i] )*(array1[i] - array2[i]);
Run Code Online (Sandbox Code Playgroud)
如果我查看源代码以查看繁重发生的位置,OpenCV人员的for循环在循环的每次迭代中一次执行4个平方差计算.执行块匹配的功能如下所示.
int64
icvCmpBlocksL2_8u_C1( const uchar * vec1, const uchar * vec2, int len )
{
int i, s = 0;
int64 sum = 0;
for( i = 0; i <= len - 4; i += 4 )
{
int v = vec1[i] - vec2[i];
int e = v * v;
v = vec1[i + 1] - vec2[i + 1];
e += v * v;
v = vec1[i + 2] - vec2[i + 2];
e += v * v;
v = vec1[i + 3] - vec2[i + 3];
e += v * v;
sum += e;
}
for( ; i < len; i++ )
{
int v = vec1[i] - vec2[i];
s += v * v;
}
return sum + s;
}
Run Code Online (Sandbox Code Playgroud)
此计算用于无符号8位整数.它们在此函数中对32位浮点执行类似的计算:
double
icvCmpBlocksL2_32f_C1( const float *vec1, const float *vec2, int len )
{
double sum = 0;
int i;
for( i = 0; i <= len - 4; i += 4 )
{
double v0 = vec1[i] - vec2[i];
double v1 = vec1[i + 1] - vec2[i + 1];
double v2 = vec1[i + 2] - vec2[i + 2];
double v3 = vec1[i + 3] - vec2[i + 3];
sum += v0 * v0 + v1 * v1 + v2 * v2 + v3 * v3;
}
for( ; i < len; i++ )
{
double v = vec1[i] - vec2[i];
sum += v * v;
}
return sum;
}
Run Code Online (Sandbox Code Playgroud)
我想知道是否有人有任何想法如果打破一个4块这样的块可能会加快代码?我应该补充一点,在这段代码中没有发生多线程.
我的猜测是,这只是展开循环的一个简单实现- 它在循环的每次传递中节省了 3 次加法和 3 次比较,例如,如果检查len涉及缓存未命中,这可能是一个很大的节省。缺点是这种优化增加了代码复杂性(例如,如果长度不能被 4 整除,则在末尾附加 for 循环来完成剩余 len % 4 项的循环),当然,这是一种依赖于体系结构的优化其改进幅度将因硬件/编译器/等而异......
尽管如此,与大多数优化相比,它仍然很容易遵循,并且无论架构如何,都可能会导致某种性能的提高,因此将其扔在那里并希望得到最好的结果的风险很低。由于 OpenCV 是一个得到良好支持的代码块,我确信有人对这些代码块进行了检测,并发现它们非常值得 - 正如您自己所做的那样。
| 归档时间: |
|
| 查看次数: |
6013 次 |
| 最近记录: |