工具/软件:
我将 TI C2000编译器与以下优化标志配合使用:
/opt/ti/ti-cgt-c2000_22.6.1.LTS/bin/cl2000 \ --issue_remarks --gen_opt_info=2 -v28 -ml -O4 -op=3 \ --c_src_interlist --auto_inline --verbose_diagnostics \ --advice:performance=all --opt_for_speed=5 \ --preproc_with_compile --keep_asm \ -I/opt/ti/ti-cgt-c2000_22.6.1.LTS/include \ main.cpp
`、我注意到 μ C-O4`
优化级别的代码优化行为存在一些效率低下问题、我想问问是否有任何解决这些问题的建议或见解。
静态表优化
在第一个示例中table[]
foo()
,我在函数中有一个静态,我希望编译器优化此表并删除不必要的内存访问。 但是、即使的值a
在表的范围内、仍直接访问表。 相比之下、优化级别的 GCC-O1
可以更高效地处理此问题。 是否有任何方法可以确保正确优化扫描床?
/* MOVZ AR6,AL ; [CPU_ALU] |4| MOVL XAR4,#_table$1 ; [CPU_ARAU] |6| SETC SXM ; [CPU_ALU] MOVL ACC,XAR4 ; [CPU_ALU] |6| ADD ACC,AR6 ; [CPU_ALU] |6| MOVL XAR4,ACC ; [CPU_ALU] |6| MOV AL,*+XAR4[0] ; [CPU_ALU] |6| LRETR ; [CPU_ALU] */ int foo(char a) { static const int table[] = { 1,2,3,4,5 }; return table[a]; }
自动内联
在第二个示例中、read()
函数很简单、理想情况下应被内联、尤其是在给定--auto_inline
flag 的情况下。 但是、编译器似乎未内联此函数。 GCC-O1
自动内联。 为什么这个函数即使与一起也没有内联到 C2000编译器中-O4
、是否有其他标志可以确保这一点?
我还观察到编译器会生成一个不必要的调用memcpy()
,这对于性能来说并不理想。 代码本质上是在使用更简单的指令可以完成的值周围移动、因此我很惊讶地看到 memcpy 调用。 如何避免此问题、或者是否有可以更好地优化此模式的设置?
/* ADDB SP,#4 ; [CPU_ARAU] MOV PL,#65012 ; [CPU_ALU] |2| MOVZ AR4,SP ; [CPU_ALU] |8| MOV PH,#16180 ; [CPU_ALU] |2| MOVL ACC,XAR6 ; [CPU_ALU] |7| MOVL *-SP[4],P ; [CPU_ALU] |2| SUBB XAR4,#4 ; [CPU_ARAU] |8| MOV PL,#65012 ; [CPU_ALU] |2| MOV PH,#16180 ; [CPU_ALU] |2| MOVZ AR5,AR4 ; [CPU_ALU] |8| MOVL *-SP[2],P ; [CPU_ALU] |2| B $C$L1,EQ ; [CPU_ALU] |8| MOVL XAR4,ACC ; [CPU_ALU] |8| MOVB ACC,#4 ; [CPU_ALU] |8| LCR #_memcpy ; [CPU_ALU] |8| << Whoooh! SUBB SP,#4 ; [CPU_ARAU] LRETR ; [CPU_ALU] */ struct float2 { float2(float x, float y) : x(x), y(y) {} float x, y; }; // Should be auto inlined (called once) float2 read() { return float2(0.707f, 0.707f); } float test() { float2 v = read(); return v.x + v.y; }
如果您有任何使用 TI C2000编译器改进这些用例优化的见解或建议、我将不胜感激。