1 通用的调整性能的策略
1.1 选择恰当的编译器选项
- 必须要用的选项 –O[2|3]
- 可以使用-mt(要确保写的数据和读的数据在内存空间上没有重合)
- -mh<num> Specify speculative load byte count threshold
- 如果源代码里含有永远不会执行的代码,使用选项-mo Place each function in a separate subsection
- 如果考虑可执行程序的大小,加上-ms[0-3]。(我在C64x+上编译时,加此选项,连接错误,提示找不到__push_rts?原因不明)
- 不要加上-g –gp –ss –ml3 –mu
- (-s[–k –al] –o[2|3] –mw (-on2 –o3) –consultant 可以在产生分析信息的同时不影响生成代码的性能
1.2 确保循环中的次数变量(一般for(i; i<N; i++), 此处的i)是有符号整数。
1.3 给编译器提供尽可能多的信息,如限定符restrict, 编译指示MUST_ITERATE、_nasserts()等。
1.4 内存中数据结构的对齐,可使用DATA_ALIGN、 STRUCT_ALIGN等
1.5 参考Compiler Consultant和.nfo文件的建议信息
2 利用优化器的意见
当编译选项中有-s时,在生成的*.asm文件中会有优化器的意见
如"C:/CCStudio_v3.3/C6000/cgtools/bin/cl6x" -g -k -s -on2 -o3 -mt -mw -mv6400+ --mem_model:data=near --consultant -@"Debug.lkf" "lesson_c.c"
其中
void lesson_c(short *xptr, short *yptr, short *zptr, short *w_sum, int N)
{
int i, w_vec1, w_vec2;
short w1,w2;w1 = zptr[0];
w2 = zptr[1];
for (i = 0; i < N; i++)
{
w_vec1 = xptr[i] * w1;
w_vec2 = yptr[i] * w2;
w_sum[i] = (w_vec1 + w_vec2) >> 15;
}}
生成的优化器意见为:
;** --------------------------------------------------------------------------*
;** 27 ----------------------- w1 = *zptr;
;** 28 ----------------------- w2 = zptr[1];
;** 29 ----------------------- if ( N <= 0 ) goto g4;;** --------------------------------------------------------------------------*
;** ----------------------- U$17 = xptr;
;** ----------------------- U$20 = yptr;
;** ----------------------- U$26 = w_sum;
;** 31 ----------------------- L$1 = N;
;** ----------------------- #pragma MUST_ITERATE(1, 1099511627775, 1)
;** ----------------------- #pragma LOOP_FLAGS(4096u)
;** -----------------------g3:
;** 31 ----------------------- *U$26++ = _mpy(*U$17++, w1)+_mpy(*U$20++, w2)>>15;
;** 29 ----------------------- if ( --L$1 ) goto g3;
;** -----------------------g4:
;** ----------------------- return;从中可以看出,加入了对N是否0的判断。如果改为:
void lesson_c(short *xptr, short *yptr, short *zptr, short *w_sum, int N)
{
int i, w_vec1, w_vec2;
short w1,w2;w1 = zptr[0];
w2 = zptr[1];
#pragma MUST_ITERATE(1) //至少循环一次
for (i = 0; i < N; i++)
{
w_vec1 = xptr[i] * w1;
w_vec2 = yptr[i] * w2;
w_sum[i] = (w_vec1 + w_vec2) >> 15;
}}
相应的意见为,没有了对N是否为0的判断
;** --------------------------------------------------------------------------*
;** 27 ----------------------- w1 = *zptr;
;** 28 ----------------------- w2 = zptr[1];
;** ----------------------- U$15 = xptr;
;** ----------------------- U$18 = yptr;
;** ----------------------- U$24 = w_sum;
;** 32 ----------------------- L$1 = N;
;** ----------------------- #pragma MUST_ITERATE(1, 4294967295, 1)
;** ----------------------- #pragma LOOP_FLAGS(4096u)
;** -----------------------g2:
;** 32 ----------------------- *U$24++ = _mpy(*U$15++, w1)+_mpy(*U$18++, w2)>>15;
;** 30 ----------------------- if ( --L$1 ) goto g2;
;** -------------