Pentium III处理器的单指令多数据流扩展指令(3)
2010-10-15 09:08:09 来源:Web开发网2. 内存问题
2.1 对齐
简单的处理和使用新数据类型变量是没有问题的.然而,一个推荐的做法是使用16字节边界对齐来定义新数据类型变量.可以通过设置一个特定的编译器参数或者在变量声名时显式的使用一个对齐标记来实现.
声名变量时可以指定__declspec编译器标记来强制变量使用16字节边界对齐,就像下面的例子代码所示.下面的变量myVar在使用这个对齐标记以后将被强制到16字节边界对齐.但当在直接声明这个新数据类型变量(也就是SSE定义的128位新数据类型)时就不需要指定这个对齐标记了,编译器会在遇到这个新数据类型时自动按16字节对齐.下面是对齐标记的用法 :
__declspec(align(16)) float[4] myVar;
2.2 动态分配
由于新数据类型要求的16字节边界对齐,使得在动态分配内存或者用指针来分配内存时会产生问题.
当使用指针访问数组时,我们必须保证这个指针是16字节边界对齐的.
在运行时分配内存可以使用malloc或者new命令.默认情况下这两种方法分配的指针都不是16字节边界对齐的.因此我们必须把这个分配得到的指针转换到16字节对齐,或者使用_mm_malloc函数来分配内存.使用_mm_malloc函数分配的内存块是按16字节边界对齐的. 和malloc函数有一个free函数一样,_mm_malloc函数也有一个对应的函数_mm_free.分配内存块使用_mm_malloc函数而清除(free)内存块用_mm_free函数.
2.3 自定义数据类型
指针必须是16字节边界对齐的限制很麻烦,如果能够不理睬这种限制就好了.
在使用128位新数据类型时,我们经常需要去访问储存在里面的(4个)浮点数.在使用汇编语言时我们没有许多的选择.但在使用C或者C++和intrinsics库时,我们总是用__mm128数据类型来表示这个128位的数据.使用这种数据类型(__mm128)时,一旦这个数值被设置以后,我们就不大可能直接去访问存储在里面的单独的浮点数了.有一个途径是把存储在里面的浮点数转移到一个浮点数数组里面,修改他们的数值以后再把他们转换回去.另一种途径是把这个新的数据类型映射到一个浮点数数组的方法来访问这些必要的元素.上面的第一种方法比较浪费时间而第二种方法如果使用不当则会发生问题.
定义一个自定义的数据类型能够避免这个问题.这个自定义的数据类型用联合(union)的方法把新数据类型(__mm128)和一个4个元素的浮点数数组关联起来.下面给出代码,现在可以用sse4来声名新数据类型了.
union sse4 {
__m128 m;
float f[4];
};
使用上面定义的数据类型,声明变量时不必使用对齐标记来强制16字节对齐,因为编译器在遇到这个数据联合里面的__m128数据类型时会自动按16字节对齐来分配内存的.这个数据类型的一个好处就是可以直接访问到存储在里面的单独的浮点数.
更多精彩
赞助商链接