Board logo

标题: GCC中SIMD指令的应用方法--性能优化 [打印本页]

作者: look_w    时间: 2018-5-9 19:59     标题: GCC中SIMD指令的应用方法--性能优化

当使用C/C++完成了一个嵌入式应用的所有功能,性能问题常摆在面前, 这时可以使用profile工具(如gprof)找出产生瓶颈的函数, 将这些函数使用汇编彻底重写, 例如MPEG-4编解码器xvid项目 [4]就使用了这种方法, 而且针对不同处理器/指令集分别给出了不同的优化, 正是如此该项目无论功能、还是性能均为一流, 显然这是深度优化的目标所在。
在使用流水线、VLIW以及SIMD的体系结构(比如某些DSP)上, 整个函数的手工优化可以带来几倍到几十倍的性能提升。 不过,性能允许,对于函数内关键部分使用一些特定的实现, 既突出重点提高性能,又可以尽多地利用C/C++的高级特征, 相对缩短开发周期。 下面给出使用GCC时,应用MMX指令的几种混合编程方法:
Intel C/C++ 编译器intrinsics ...Intel C/C++ Compiler Intrinsics查看IA-32 Intel指令集手册 时, 部分指令的解释中会有一项“Intel C/C++ Compiler Intrinsic Equivalent”, 会指出该指令对等的intrinsic。 intrinsic在C/C++程序中的语法是以函数形式出现, 编译时可以直接翻译为一条MMX指令(复合情况会生成最直接的几条), 换言之,如果不使用intrinsic,可能需要多条C/C++语句完成, 而编译器却并不能保证将这几条语句能够生成这条最高效的MMX指令。 并不是每条MMX指令都有对等的intrinsic, 手册的附录中列出了所有的, 它们分为简单型(simple)和复合型(composite)两种, 每个简单型的就是对应一条指令,而复合型则对应多条指令。      
GCC支持Intel C/C++ Compiler Intrinsics。用法如下示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <stdio.h>
#include <xmmintrin.h> /*一定需要包括此头文件*/
/*gcc -Wall -march=pentium4 -mmmx -o ins  mmx_ins.c*/
int main(int argc,char *argv[])
{
  /*使用MMX做以下向量的点积*/
  short in1[] = {1, 2, 3, 4};
  short in2[] = {2, 3, 4, 5};
  int out1;
  int out2;
  __m64 m1;    /* MMX支持64位整数的mm寄存器 */
  __m64 m2;    /* MMX操作需要使用mm寄存器 */
  __m128 m128; /* for SSEn only*/
  /*每次往mm寄存器装入两个short型的数,注意是两个*/
  m1 = _mm_cvtsi32_si64(((int*)in1)[0]);
  m2 = _mm_cvtsi32_si64(((int*)in2)[0]);
  /*一条指令进行4个16位整数的乘加*/
  /*生成两个32位整数*/
  m2  = _mm_madd_pi16(m1, m2);
  /*将低32位整数放入通用寄存器*/
  out1 =  _mm_cvtsi64_si32(m2);
  /*将高32位整数右移后,放入通用寄存器*/
  m2  = _mm_slli_pi32(m2, 32);
  out2 =  _mm_cvtsi64_si32(m2);
  /*清除MMX状态*/
  _mm_empty();
  /*将两个32位数相加,结果为8*/
  out1 += out2;
  printf("a: %d\n", out1);
  return(0);
}




几点说明:





欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/) Powered by Discuz! 7.0.0