
直接使用 ^^^
嵌入汇编sse指令和 *** 作寄存器
例如一个利用sse的快速填充像素的小程序
#include <time.h>#include <stdio.h>
#define MAX_PIXELS 0x6400000
#define COLOR 0xaabbccdd
int main () {
int *p = new int[MAX_PIXELS]
clock_t start, finish
int a[4] = {COLOR, COLOR, COLOR, COLOR}
start = clock()
asm("movdqa %0, %%xmm0\n"::"m"(a))
for (register long i=0 i<MAX_PIXELS i+=4) {
asm("movdqa %%xmm0, %0\n"::"m"(p[i]))
}
finish = clock()
printf ("%lf ms\n", (double)(finish - start)*1000/CLOCKS_PER_SEC)
delete p
return 0
}
在PC上,需要得到两个版本的Qt,分别是:Qt-4.5.2和QtEmbedded-4.5.2-arm。前者包括了QtDesigner等基本工具,用于在PC上对程序的开发调试,使能确保程序放到板子上之前就符合设计的要求;然后用后者的库将调试好的程序编译成能在arm-linux平台上运行的程序。
Qt-4.5.2用从网上下载到的qt-x11-opensource-src-4.5.2.tar.gz编译后安装得到;QtEmbedded-4.5.2-arm用qt-embedded-linux-opensource-src-4.5.2.tar.gz编译后安装得到,Qt-embedded-linux-opensource-src-4.5.2.tar.gz还可以编译成Qt Embedded-4.5.2-X86,但不需要。在编译qt-embedded-linux-opensource-src-4.5.2.tar.gz之前,必须准备好arm-linux-gcc交叉编译工具,用的是arm-linux-gcc-3.4.1。
所以先要准备好的软件包有:
Pc的 *** 作系统是:LINUX-ubuntu8.04。
下面是具体编译安装过程:
1、Qt-4.5.2的获得将qt-x11-opensource-src-4.5.2.tar.gz复制到目录:/home/chh/Project/qt,
2、然后解压:
#tar zxvf qt-x11-opensource-src-4.5.2.tar.gz
得到一个新目录:qt-x11-opensource-src-4.5.2
cd进入这个目录,准备开始编译。
3、在终端中这样 *** 作:
#./configure –qvfb //编译配置,此过程大概历时几分钟; #make //正式编译,过程漫长,大概2个多小时; #cd tools/qvfb //进入此目录,准备对它进行编译 #make //编译,几分钟 #cd ../.. //回到qt-x11-opensource-src-4.5.2主目录,准备安装 #make install //安装,十几分钟吧;
4、此步必须以root身份完成,否则无法建立目录
5、可以在/usr/local/下看到一个Trolltech目录,进入该目录发现Qt-4.5.2目录已经出现,进入里面的bin目录,Designer等工具已经可以使用了。
6、编译过程相当费时,所以可以直接拷贝已经编译过的源码,直接make install。
7、至此,Qt-4.5.2的安装已经顺利完成。
QtEmbedded-4.5.2-arm的获得
在编译安装qt-embedded-linux-opensource-src-4.5.2之前,必须先配置好arm-linux-gcc,将arm-linux-gcc-3.4.1.tar.bz2解压到目录:/usr/local下,此时local下出现一个名为arm的目录,然后配置好环境变量:在/etc/profile添加一句:export PATH=$PATH:/usr/local/arm/3.4.1/bin,保存后#source /etc/profile一下,让它即时生效。 否则下面的编译过程会提示找不到arm-linux-gcc命令。 现在可以开始编译了:
将qt-embedded-linux-opensource-src-4.5.2.tar.gz复制到目录:/home/chh/Project/qt, 然后解压:#tar zxvf qt-embedded-linux-opensource-src.tar.gz, 得到新目录qt-embedded-linux-opensource-src-4.5.2。
进入qt-embedded-linux-opensource-src-4.5.2目录,首先进行configure。 这里的参数很重要,必不可少的是-embedded arm,所以最简单的配置信息可以这样:
./configure \ -embedded arm
然后回车,就开始configure了,参数设置和参考文章一样,裁减了很多,减少了编译时间:
./configure \ -release \ -shared \ -fast \ -no-largefile \ -qt-sql-sqlite \ -no-qt3support \ -no-xmlpatterns \ -no-mmx \ -no-3dnow \ -no-sse \ -no-sse2 \ -no-svg \ -no-webkit \ -qt-zlib \ -qt-gif \ -qt-libtiff \ -qt-libpng \ -qt-libmng \ -qt-libjpeg \ -make libs \ -xplatform qws/linux-arm-g++ \ -nomake tools \ -nomake examples \ -nomake docs \ -nomake demo \ -no-nis \ -no-cups \ -no-iconv \ -no-dbus \ -no-openssl \ -embedded arm \ -little-endian \ -qt-freetype \ -depths 16,18 \ -qt-gfx-linuxfb \ -no-gfx-transformed \ -no-gfx-multiscreen \ -no-gfx-vnc \ -no-gfx-qvfb \ -qt-kbd-usb \ -no-glib
之后就可以编译了,#make,漫长等待后再 #make install。Make install还是需要root权限。
完成后,在/usr/local/Trolltech下多了一个目录:Qt Embedded-4.5.2-arm。
SIMD的全称是Single Instruction Multiple Data (单指令多数据流)。
在支持SIMD的CPU中,包含着一些特别宽的寄存器(比如512位)。通过特别的指令,可以在这些寄存器上执行指定 *** 作。这些 *** 作通常是对正常寄存器(比如64位)上 *** 作的拓展,可以理解为一条指令同时 *** 作了多个正常寄存器,也就是所谓的SIMD了。
做个简单的除法就能知道,512位的寄存器相比64位寄存器,速度提升了8倍。
但是实际情况不仅仅是如此。在SIMD的指令中,还包括了一些非常奇妙的指令,比如计算正态分布的累积分布函数和其反函数的指令。在看到它们的时候,我心里吼了一句:“还有这种 *** 作!”。这些特化的指令在特别的场景下就是神器。
首先,我们是在Linux的GCC编译器上使用SIMD指令。在这个条件下,有两个途径:
嵌入式汇编不是今天的主题。我今天主要记录一下Intrinsics怎么用。不管使用哪种方法,有一个网站是一定要收藏的: Intel Intrinsics Guide
它给出了SIMD指令集的各个子集: MMX, SSE,SSE4.2,AVX2等等。同时,它给每个指令都打上一些标签用于检索:Load,Store,Cast,Arithmetic 等等。它还给出了每个指令的等价 *** 作和汇编指令。
具体地说,在C语言中使用SIMD涉及三个方面:
头文件和函数调用很好办,它归属于Intel的规范。在Intel Intrinsics Guide中,每条指令需要的头文件都有标注,按图索骥即可。
编译选项则属于GCC的规范。 i386 and x86-64 Options 将相关选项包含在内,但是更宽一些。每条指令都有所属的指令集(比如SSE4.2),当使用到该指令后,就要在链接器的选项中加上相关的项 (比如 -msse4.2 ) 。
选项的命名很直接,在 i386 and x86-64 Options 里搜索 -mmmx 就可以跳到SIDM选项比较集中的区域,很容易就能确定需要的选项是什么。
使用SIMD指令的范式很简单:
这里涉及到一个问题,就是导入导出使用到的内存必须满足特殊的对齐条件。比如使用了128位(16字节)的SIMD,则内存首地址必须能被16整除。如果不满足该条件,在导入数据时程序会引发段错误退出。
在C中,获得特定对齐方式的动态内存,使用的函数是来自 stdlib.h 的 void* aligned_alloc(size_t alignment, size_t size) 。
编译的指令如下:
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)