1. 当心运用汇编表达式
在C/C++代码中,有时分一些操作不免会对某些CPU寄存器进行操作,此刻要运用内嵌的汇编表达式,例如asm(“EALLOW”),或许重置某个中止的掩码寄存器等。在优化代码时,编译器会从头调整某些代码段的次序,自己决议运用某些寄存器(例如AR0-AR7这样的辅佐寄存器),乃至删去某些编译器以为无用的变量、函数等,可是编译器一般状况下并不会对内嵌的汇编代码进行任何优化(除非这段汇编代码被编译器以为是永久不会履行到的无用代码),这就造成了编译器的优化作用在这段汇编代码和它的上下文代码中无法进行有用的优化,特别是汇编代码和C/C++代码直接存在变量调用的状况下。所以非必要的状况下,要尽量防止C/C++和汇编句子的混用,假如的确需求的,也要在编译之后查看生成的汇编代码是不是确保了咱们代码本意的完整性。
2. 为必要的内存存取运用volatile关键字
在C/C++代码的编译过程中,编译器会剖析数据流,然后尽量防止对存储空间的直接存取。可是假如咱们要在C/C++代码中直接对内存地址进行操作的话,需求运用volatile关键字来界说变量,编译器在优化时不会对volatile类型的变量进行优化。
例如,鄙人面的代码中,循环的完毕条件为指针指向的地址为0xFF:
unsigned int *ctrl;
while (*ctrl !=0xFF);
由于*ctrl是一个不变的表达式,这个循环会被优化为一次内存读取。为了正的确现咱们的代码目的,需求把ctrl界说为volatile类型:
volatile unsigned int *ctrl
运用volatile类型界说的类型在调试的时分还有一个极大的优势,便是咱们能够直接在CCS的debug窗口里改动变量的值,极大地便利咱们的调试。
3. 当心运用Alias变量
Alias(别号)在一个变量能够被至少两种方法存取的时分会用到,例如,当两个指针指向同一块区域或目标时,咱们称一个指针 alias 另一个指针。Alias变量的运用要十分慎重,由于会涉及到非直接的引证,然后破坏了优化作用。编译器在优化时会剖析代码来决议在哪些地方会发生alias引证,然后在坚持代码正确性的基础上“保存”地优化代码。
一般状况下,编译器会假定,假如一个本地变量的地址被传递给某个函数,则这个函数有可能会经过指针操作改动这个本地变量的内容,可是这个函数不能在该地址被回来后依然能够被其他指针操作所示运用,例如把这个本地变量的地址分配给一个全局变量或许回来它。假如这种假定被打破,则需求在编译器选项里运用-ma强制编译器依照最坏状况的别号引证来进行必定的优化,在这种状况下,任何非直接的引证(例如运用指针)都能够引证到这个变量。
4. 何时运用–aliased_variables选项?
编译器在优化时会假定,任何变量的地址在作为参数被传递给某个函数时,都不会在调用它的函数里被任何Alias变量修正,例如:从函数回来地址,或许把地址分配给某个全局变量。可是假如咱们运用办理相似下面操作的代码的时分,就需求运用–aliased_variables选项来优化代码:
int *glob_ptr;
g()
{
int x = 1;
int *p = f(&x);
*p = 5; /* p是x的别号 */
*glob_ptr = 10; /* glob_ptr 也是 x的别号 */
h(x);
}
int *f(int *arg)
{
glob_ptr = arg;
return arg;
}
5. 含有FPU的器材:运用restrict关键词来标明指针没有被别号操作
在含有FPU浮点协处理器的器材中,当运用–opt_level=2(优化寄存器、局部变量和全局变量的运用)的优化等级时,优化器会剖析代码的依靠性。为了更好地协助优化器完结内存的依靠联系,咱们能够把指针、引证或许数组等的声明中参加restrict关键词。restrict关键词是C99规范引进的,它会告知编译器,一切修正该指针所指向内存中内容的操作都必须经过该指针来修正,而不能经过其它途径(其它变量或指针)来修正。运用这一原则能协助编译器优化某些代码段,由于别号信息能够被愈加快速地承认。运用restrict关键词后由于能够履行更多的FPU操作,而FPU操作与CPU是并行的,所以带来的优化作用是提高了功能和减小了代码尺度。
咱们能够运用下面比如中的代码来告知编译器,a和b永久不会在函数foo中指向同一个地址,而且a和b的内存地址也不会相互掩盖(阐明它们没有依靠性,能够并行履行)。
void foo(float * restrict a, float * restrict b)
{
/* foo’s code here */
}
或许
void foo(float c[restrict], float d[restrict])
{
/* foo’s code here */
}