在这篇博客中,我将会给大家分享关于OpenCV源码中的CPU指令集CV_SSE2等的相关知识
一、
CV_SSE系列指令集的预编译符号定义在opencv2/core/internal.hpp这个头文件中,如果你不包含这个头文件的话,把源码拷贝到自己的函数中,CV_SSE是不被定义的
下面是harrisCorner中的一部分代码
/*该函数的主要作用是利用给定的梯度协矩阵计算每一个点上的harris角点响应强度矩阵*/
static void calcHarris( const Mat& _cov, Mat& _dst, double k )
{
int i, j;
Size size = _cov.size();
#if CV_SSE
volatile bool simd = checkHardwareSupport(CV_CPU_SSE); //获取CPU指令集优化状态
#endif
if( _cov.isContinuous() && _dst.isContinuous() )
{
size.width *= size.height;
size.height = 1;
}
for( i = 0; i < size.height; i++ )
{
const float* cov = (const float*)(_cov.data + _cov.step*i);
float* dst = (float*)(_dst.data + _dst.step*i);
j = 0;
#if CV_SSE
//如果CPU支持SSE指令集优化的话(CV_SSE有定义),而且当前允许使用指令集优化,
//(simd 状态为真)则下面这段代码将被执行
if( simd )
{
__m128 k4 = _mm_set1_ps((float)k);
for( ; j <= size.width - 5; j += 4 )
{
__m128 t0 = _mm_loadu_ps(cov + j*3); // a0 b0 c0 x
__m128 t1 = _mm_loadu_ps(cov + j*3 + 3); // a1 b1 c1 x
__m128 t2 = _mm_loadu_ps(cov + j*3 + 6); // a2 b2 c2 x
__m128 t3 = _mm_loadu_ps(cov + j*3 + 9); // a3 b3 c3 x
__m128 a, b, c, t;
t = _mm_unpacklo_ps(t0, t1); // a0 a1 b0 b1
c = _mm_unpackhi_ps(t0, t1); // c0 c1 x x
b = _mm_unpacklo_ps(t2, t3); // a2 a3 b2 b3
c = _mm_movelh_ps(c, _mm_unpackhi_ps(t2, t3)); // c0 c1 c2 c3
a = _mm_movelh_ps(t, b);
b = _mm_movehl_ps(b, t);
t = _mm_add_ps(a, c);
a = _mm_sub_ps(_mm_mul_ps(a, c), _mm_mul_ps(b, b));
t = _mm_mul_ps(_mm_mul_ps(k4, t), t);
a = _mm_sub_ps(a, t);
_mm_storeu_ps(dst + j, a);
}
return;
}
#endif
//不启用指令集优化时这段普通代码将被执行
for( ; j < size.width; j++ )
{
float a = cov[j*3];
float b = cov[j*3+1];
float c = cov[j*3+2];
dst[j] = (float)(a*c - b*b - k*(a + c)*(a + c));
}
}
}
二、
CPU指令集优化功能可以根据需要开启或关闭:
首先可以使用此函数
bool cv::useOptimized()
来查询当前是否开启了CPU指令集优化功能,
可以使用函数
void cv::setUseOptimized(bool onoff)
来设置是否开启CPU指令集优化功能;
可以使用此函数
bool checkHardwareSupport(int feature);
来查询你的CPU是否支持某种指令集优化特性。
feature的取值有以下几种:
请看一下代码:
#include
#include
using namespace std;
using namespace cv;
int main(int argc ,char** args)
{
//设置是否启用指令集优化特性
cv::setUseOptimized(true);
//获取当前机器的CPU指令集支持特性
bool opt_status = cv::useOptimized();
cout<<"当前的指令集优化状态:"<
<
在上述代码中,如果setUseOptimized()函数的参数为true的话,则CPU的硬件指令优化功能被开启,状态函数opt_status = cv::useOptimized()返回为真,
而且在上述代码中我们查询了我的机器的CPU指令优化支持特性,我的CPU型号为Inter Core(TM) i5 650 的,查询结果显示如下:
可以看到,我的CPU支持绝大多数的指令集优化特性,只有最后一个CPU_AVX是0,尽管我们用程序指令开启了指令集优化特性,但是CPU_AVX依然是0,这就说明我的CPU在硬件层面上不提供CPU_AVX的优化功能,即使setUseOptimized()函数的参数为true,也无法使用此功能。
如果setUseOptimized()函数的参数为false的话,则CPU的硬件指令优化功能被关闭,状态函数opt_status = cv::useOptimized()返回为假,上述代码的运行结果为
可以看到,此时所有的CPU指令集优化功能都被禁止了,即使CPU硬件本身支持的特性,也被禁止使用了。
所以在你的程序中,你可以在main()主函数中通过setUseOptimized()函数来设置是否启用OpenCV的指令集优化功能