如何使VC6.0支持内嵌SSE指令如何使VC6.0支持内嵌SSE指令在学习MMX/SSE/SSE2/SSE3/SSSE3/SSE4.1指令的时候,我很喜欢一边学习新的知识点;一边使用它们来嵌入代码中进行巩固和再次理解。很遗憾,在默认安装情况下VC6.0不支持MMX/SSE指令,比如我在代码中嵌入如下代码:
VC编译器会告诉你XMM0不认识等一堆的错误,这个主要原因是VC没有安装对应的SSE支持包。那么如何获取和安装它呢?很简单,到微软网站上搜索一下就ok了,为了节省大家的时间,这里贴上对应的下载路径: http://download.microsoft.com/download/vb60ent/update/6/w9x2kxp/en-us/vcpp5.exe 因为我安装的是VC6.0英文企业版,所以它已经在我机器上成功安装了。如果是其他版本,我建议还是到它的网站上确认一下是否有相关版本J。 在一段漫长(我用的网络很慢,流量也受到控制L)的等待后,下载终于被完成了,我迫不及待的双击了vccp5.exe。很遗憾,在安装到一半的时候,错误对话框弹出,说这个SSE支持包要在安装了VC6.0 service pack5的基础上才能安装!我昏了过去(还好,头没有把我的电脑桌撞坏L)!没有办法,还得继续找那个VC6.0 SP5。在微软网站上兜了一会儿,我终于发现了它的身影,呵呵,往哪里逃!下载路径如下: http://download.microsoft.com/download/vstudio60ent/SP5/Wideband-Full/WIN98Me/EN-US/VS6sp5.exe 虽然是找到了,但是它的大小却下了我一跳,要130多M。我那该死的破网络啊,一边吐血,一边硬着头皮上,在大概2个小时的下载后,我终于从苦海中出头了J! 还是老老实实的按步骤安装 吧: 1. 安装VS6sp.exe 2. 安装vcpp5.xe 再献血500CC后,所有的内嵌SSE指令都能够编译和运行了,呵呵,可以继野啃SSE啦! 希望上面的心得能够帮助那些和我一样恨VC6.0不成钢的网友们,给他们一些新的希望,节省他们宝贵的时间!如果那位有intel c/c++编译器的朋友,那就请毫不犹豫的用它吧,这个方面它强多了,并且优化能力也是相当厉害的!可惜,我down了一个试用版本,用的不爽,所以就走了一段曲折的老路5555555~~~。 发表于 @ 2008年11月22日 09:18:00|评论(14 )|收藏 新一篇: 如何使用SSE指令提高FIR算法效率 | 旧一篇: 留言簿 |
|
评论
另 外,Intel编译器十分强大,我们公司使用正版的。Intel C/C++ Compiler10.x的代码优化能力比VC2008更强,非常厉害。如果单做内存拷贝等更本做不过它。有时像一些特定的算法,如矩阵转置、矩阵乘法、 以及其他一些SSE、MMX占优势的算法时才能超过它。
另外,Intel C/C++ Compiler10.x完全兼容VC2005,而且还有扩充,它扩充到SSE4.1的内建函数,非常厉害。而MSDN2008上最多只有SSE3内建函数的支持。
以后有机会与你多多交流。
比如:
__m128 _mm_xxxxxxxx(xxxxx)
{
__asm
{
你的汇编代码
}
}
难道不可以吗?
比如说,Intrinsic Function中没有movd xmmReg, mem32
那么我现在要构建这么一个Intrinsic Function:
__m128i _mm_loadl_epi32(__m128i const*p)
{
__m128i xmmReg;
__asm
{
mov edx, dword ptr [p]
movd xmm0, dword ptr [edx]
movdqa xmmword ptr [xmmReg], xmm0
}
return xmmReg;
}
你看看,需要多少步。而且里面内嵌的汇编,C/C++编译器是不会帮你做任何优化的。
而如果是基于GNU的C/C++编译器的话,里面的内敛汇编就非常好了。比如说:
asm("movd %0 dword ptr [%1];" : "=xmm"(xmmReg) : "d"(p));
这 里面有输入输出指示符以及寄存器使用指示符。比如说,从标号0到1分别对应=xmm和d。其中,xmm指示编译器使用一个XMM寄存器;d指示编译器使用 一个通用数据寄存器。而=表示输出,即将xmm寄存器的结果直接给到xmmReg变量;而后一个是输入,表示将参数变量p的值传给通用数据寄存器。
这样以来,C/C++编译器根据内联汇编的指示进行自适应优化,就能得到一个Intrinsic的效果了。
你 认为VC不会帮助我们对程序员自己输入的汇编代码进行优化,所以在可能一定程度上降低效率,而GCC可能会更具当前插入内联汇编代码的上下文进行优化处 理,比如说,它可以挑选用那个XMM寄存器(如果上面的某个代码使用了XMM0,的话,我们再次鲁莽使用可能会导致错误或者效率低下。)对吗?
我有一个想法,不知道是否可行。如果出现这种情况,我们就在一个单独的函数中仅仅用汇编代码,避免出现上述错误。如果我们手上有宏汇编编译器的话,我们就可以干脆都是汇编,它反正仅仅提供一个接口函数,实现起来难度不是特别的大:-)
此外,个人感觉,intrinsic函数的提供仅仅是为了在提高效率的同时提高移植性,如果自己能够写一些函数来服务于此,即使效率差一些也无妨:-)。
__m128i _mm_loadl_epi32(__m128i const*p)
{
__m128i xmmReg;
__asm
{
mov edx, dword ptr [p]
movd xmm0, dword ptr [edx]
movdqa xmmword ptr [xmmReg], xmm0
}
return xmmReg;
}
为什么要取出第32位后在返回一个128位的东西?
PSIGNB/W/D,PEXTRB/W/D/Q等这些指令都可以方便的搞定它啊?
那段代码并不重要。
不过通过movd的内建函数可以搞定。编译器会根据你代码的上下文自己去判断到底使用movd xmmReg, reg32的形式还是使用movd xmmReg, mem32的形式。由于x86的通用寄存器也着实稀少,所以这些都可以交给编译器作处理。
这个是ASIC框架所决定的吧,不像RISC那样有一堆的寄存器可以使用:-).
对了,你们公司如果用Intel c/c++编译器对程序进行优化,那么优化后的程序如果在AMD平台上运行,有没有发现过它反而变慢?或者是等于没有优化这类的情况出现?
我猜想Intel编译器在自己的平台上做了很多工作,但是在AMD平台上可能做的不多吧?从这个角度看,有没有可能微软的编译器编译出来的代码在AMD平台上比Intel编译器要更好呢?
没有办法,重装一下SP5和SSE包吧,555555.。。。
【血的结论】:安装SSE一定要配合安装SP5包,不要耍小聪明安装SP6包!因为喜新厌旧会得报应的!做人要厚道啊!
看上去工作量还是蛮大的,毕竟两者差别还是挺大的。