开源库Simd在vs2010中的编译及简单使用

Simd是开源的图像处理库,它提供了很多高性能的算法,这些优化算法主要由SIMD指令来实现,包括SSE、SSE2、SSSE3、SSE4.1、SSE4.2、AVX等,此库可以应用在windows/linux 32bit/64bit等系统中。此库更新较频繁。此库的license是MIT。

下面详细介绍其在vs2010中的编译及使用:

1.        从https://sourceforge.net/projects/simd/?source=typ_redirect下载最新版本simd.2.2.27.443,解压缩;

2.        新建一个libSimd静态库工程,将/simd.2.2.27.443/simd/src/Simd目录下的.h、.cpp文件加入到此工程中,将../../../src/simd.2.2.27.443/simd/src/加入到C/C++--> General --> Additional Include Directories中,编译即可生成静态库,其实/simd.2.2.27.443/simd/prj/vs11中已经有了vs2012的工程配置,只是工程数太多,我把它们都放在一个工程里了;

3.  新建一个testSimd控制台工程,测试生成的libSimd库的正确性,相关代码如下:

stdafx.h:

#pragma once

#include "targetver.h"

#include <stdio.h>

#include "Simd/SimdSse2.h"
#include "Simd/SimdBase.h"

#include "../../OpenCV/2.4.9/vs2010/install/include/opencv2/core/core.hpp"
#include "../../OpenCV/2.4.9/vs2010/install/include/opencv2/highgui/highgui.hpp"
#include "../../OpenCV/2.4.9/vs2010/install/include/opencv2/imgproc/imgproc.hpp"

stdafx.cpp:

#include "stdafx.h"

#ifdef _DEBUG
	#pragma comment(lib, "../../../lib/dbg/x86_vc10/libSimd[dbg_x86_vc10].lib")

	#pragma comment(lib, "../../../../OpenCV/2.4.9/vs2010/install/x86/vc10/staticlib/zlibd.lib")
	#pragma comment(lib, "../../../../OpenCV/2.4.9/vs2010/install/x86/vc10/staticlib/IlmImfd.lib")
	#pragma comment(lib, "../../../../OpenCV/2.4.9/vs2010/install/x86/vc10/staticlib/libjasperd.lib")
	#pragma comment(lib, "../../../../OpenCV/2.4.9/vs2010/install/x86/vc10/staticlib/libjpegd.lib")
	#pragma comment(lib, "../../../../OpenCV/2.4.9/vs2010/install/x86/vc10/staticlib/libpngd.lib")
	#pragma comment(lib, "../../../../OpenCV/2.4.9/vs2010/install/x86/vc10/staticlib/libtiffd.lib")

	#pragma comment(lib, "../../../../OpenCV/2.4.9/vs2010/install/x86/vc10/staticlib/opencv_core249d.lib")
	#pragma comment(lib, "../../../../OpenCV/2.4.9/vs2010/install/x86/vc10/staticlib/opencv_highgui249d.lib")
	#pragma comment(lib, "../../../../OpenCV/2.4.9/vs2010/install/x86/vc10/staticlib/opencv_imgproc249d.lib")

	#pragma comment(lib, "comctl32.lib") 
#else
	#pragma comment(lib, "../../../lib/rel/x86_vc10/libSimd[rel_x86_vc10].lib")

	#pragma comment(lib, "../../../../OpenCV/2.4.9/vs2010/install/x86/vc10/staticlib/zlib.lib")
	#pragma comment(lib, "../../../../OpenCV/2.4.9/vs2010/install/x86/vc10/staticlib/IlmImf.lib")
	#pragma comment(lib, "../../../../OpenCV/2.4.9/vs2010/install/x86/vc10/staticlib/libjasper.lib")
	#pragma comment(lib, "../../../../OpenCV/2.4.9/vs2010/install/x86/vc10/staticlib/libjpeg.lib")
	#pragma comment(lib, "../../../../OpenCV/2.4.9/vs2010/install/x86/vc10/staticlib/libpng.lib")
	#pragma comment(lib, "../../../../OpenCV/2.4.9/vs2010/install/x86/vc10/staticlib/libtiff.lib")

	#pragma comment(lib, "../../../../OpenCV/2.4.9/vs2010/install/x86/vc10/staticlib/opencv_core249.lib")
	#pragma comment(lib, "../../../../OpenCV/2.4.9/vs2010/install/x86/vc10/staticlib/opencv_highgui249.lib")
	#pragma comment(lib, "../../../../OpenCV/2.4.9/vs2010/install/x86/vc10/staticlib/opencv_imgproc249.lib")

	#pragma comment(lib, "comctl32.lib")
#endif

testSimd.cpp:

#include "stdafx.h"
#include <iostream>
#include <string>

using namespace std;

void BgraToGrayTest()
{
	string strImageName = "../../../testdata/cat.jpg";
	int iImageWidth = 10000;
	int iImageHeight = 10000;

	cv::Mat matSrc = cv::imread(strImageName, 1);
	cv::cvtColor(matSrc, matSrc, cv::COLOR_BGR2BGRA);
	cv::resize(matSrc, matSrc, cv::Size(iImageWidth, iImageHeight), 0, 0, 1);

	cv::Mat matDst1, matDst2;
	matDst1 = cv::Mat::zeros(iImageHeight, iImageWidth, CV_8UC1);
	matDst2 = cv::Mat::zeros(iImageHeight, iImageWidth, CV_8UC1);

	int iRemainder = iImageWidth & 0x03;
	int iGrayStride =  iRemainder ? iImageWidth + 4 - iRemainder : iImageWidth;
	CV_Assert(iRemainder == 0);

	double dTimeC = cv::getTickCount();
	Simd::Base::BgraToGray(matSrc.data, iImageWidth, iImageHeight, iImageWidth * 4, matDst1.data, iGrayStride);
	dTimeC = ((double)cv::getTickCount() - dTimeC) / cv::getTickFrequency();

	double dTimeSimd = cv::getTickCount();
	Simd::Sse2::BgraToGray(matSrc.data, iImageWidth, iImageHeight, iImageWidth * 4, matDst2.data, iGrayStride);
	dTimeSimd = ((double)cv::getTickCount() - dTimeSimd) / cv::getTickFrequency();

	cout<<"C run time : "<<dTimeC<<endl;
	cout<<"Simd run time : "<<dTimeSimd<<endl;

	int iDiffCount = 0;

	for (int i = 0; i < iImageHeight; i++) {
		uchar* p1 = matDst1.ptr<uchar>(i);
		uchar* p2 = matDst2.ptr<uchar>(i);

		for (int j = 0; j < iImageWidth; j++) {
			if (p1[j] != p2[j])
				iDiffCount ++;
		}	
	}

	cout<<"the different count: "<<iDiffCount<<endl;
}

int main(int argc, char* argv[])
{
	BgraToGrayTest();

	cout<<"ok!"<<endl;
	return 0;
}

运行结果见下 图:

开源库Simd在vs2010中的编译及简单使用_第1张图片

运行多次,SIMD的执行速度基本上比C快3倍,它们的结果是完全一致的。

你可能感兴趣的:(开源库Simd在vs2010中的编译及简单使用)