mmxssesse2sse3:有关GCC下使用内建的多媒体指令集(MMX、SSE)函数

在VC2005以上版本(包括2005)有非常丰富针对x86架构处理器指令集内建包括典型BFS、RDTSC、以及MMX、3DNOW!(+)、SSE、SSE2到VC2008以后又支持了SSE3、SSSE3、以及SSE4A、SSE4.1和SSE4.2

然而当这些搬到GCC上时用起来就显得十分麻烦下面我就先举个VC2008上例子:

# <stdio.h>
# <mmrin.h>
# <emmrin.h>

(void)
{
__m64 m64Value1 = _mm_cvtsi32_si64(0x302077fe); // MOVD
__m64 m64Value2 = _mm_cvtsi32_si64(0x10203040); // MOVD

m64Value1 = _mm_insert_pi16(m64Value1, 0xab, 3);
m64Value2 = _mm_add_pi8(m64Value2, m64Value1);
m64Value2 = _mm_packs_pu16(m64Value2, m64Value1);

prf("The value is 0x%x\n", _mm_cvtsi64_si32(m64Value2));

_mm_empty;

0;
}




还是相同代码放到GCC上看看:

# <stdio.h>

typedef char __attribute__((vector_size(8))) v8qi;
typedef __attribute__((vector_size(8))) v4hi;
typedef __attribute__((vector_size(8))) v2si;

{

v8qi m64Value1 = { 0xfe, 0x77, 0x20, 0x30 };
v8qi m64Value2 = { 0x40, 0x30, 0x20, 0x10 };

m64Value1 = (v8qi)__builtin_ia32_pinsrw((v4hi)m64Value1, 0xab, 3);
m64Value2 = __builtin_ia32_paddb(m64Value2, m64Value1);
m64Value2 = __builtin_ia32_packuswb((v4hi)m64Value2, (v4hi)m64Value1);

//这里目前实在没办法使用MOVD reg32, regMMX方式
prf("The value is: 0x%x\n", *(unsigned*)&m64Value2);

0;
}


上述两段代码输出结果均为0xab00ff00



VC代码没什么可讲这里主要谈下GCC代码

首先最上面 3个类型定义是定义向量数据类型v8qi表示向量有8个单元并且每个单元都占用1个字节这里比较奇怪是这些基本类型定义GCC没有默认支持也没有放在某个特定头文件中这样要去个个定义也是比较麻烦

然后由于很多操作所基于单元大小是区别比如说PADDB每个单元是1个字节而PADDW就是2个字节因此在要做其它和变量定义区别单元个数操作时需要进行类型转换可以看到上面有很多类型转换

另外还有点比较讨厌是GCC没有提供MOVD这样基本操作使得基本类型和向量类型直接转换也比较麻烦这里做法是直接通过访问变量地址这样做会带来性能上降低不过目前也没有其它什么好办法

不过幸好GCC内联汇编功能很强我对于GCC在这方面做法还是非常看好所以本人基于GCC内联汇编便利性以及灵活性自己定义了套常用MMX以及SSE指令访问接口:

Tags:  gcc测试函数性能 mmxssesse2sse3

延伸阅读

最新评论

发表评论