诚信经营是公司制胜的法宝,与客户建立长期稳定共赢的合作关系是我们一直在努力的方向。
通过严格的质量控制,***的管理,技术,和低成本控制,我们给客户提供有竞争力的产品和优质的服务!
充足的库存,心动的价格等着您,欢迎来电详询!
我们不生产PLC,我们只做全新原装的搬运工!
ABB 3HAB8796-001 DSQC 266A
LOAD/STORE 指令中的自动索引(auto-indexing)功能就是为利用流水线延迟周期而设计的。当流水线处于延迟周期时, 处理器的执行单元被占用, 算术逻辑单元(ALU )和桶形移位器却可能处于空闲状态,此时可以利用它们来完成往基址寄存器上加一个偏移量的操作,
供后面的指令使用。例如:指令 LDR R1, [R2], #4 完成 R1= *R2 及 R2 = 4 两个操作,是后索引(post-indexing)的例子;而指令 LDR R1, [R2, #4]! 完成 R1 = *(R2 4) 和 R2 =4 两个操作,是前索引(pre-indexing)的例子。
流水线阻断的情况可通过循环拆解等方法加以改善。一个循环可以考虑拆解以减小跳转指令在循环指令中所占的比重, 进而提高代码效率。下面以一个内存***函数加以说明。
void memcopy(char *to, char *from, unsigned int nbytes)
{
while(nbytes--)
*to = *from ;
}
为简单起见,这里假设nbytes 为16 的倍数(省略对余数的处理)。上面的函数每处理一个字节就要进行一次判断和跳转, 对其中的循环体可作如下拆解:
void memcopy(char *to, char *from, unsigned int nbytes)
{
while(nbytes) {
*to = *from ;
*to = *from ;
*to = *from ;
*to = *from ;
nbytes - = 4;
}
}
这样一来, 循环体中的指令数增加了,循环次数却减少了。跳转指令带来的***影响得以削弱。利用arm 7 处理器32 位字长的特性, 上述代码可进一步作如下调整:
void memcopy(char *to, char *from, unsigned int nbytes)
{
int *p_to = (int *)to;
int *p_from = (int *)from;
while(nbytes) {
*p_to = *p_from ;
*p_to = *p_from ;
*p_to = *p_from ;
*p_to = *p_from ;
nbytes - = 16;
}
}
经过优化后,一次循环可以处理16 个字节。跳转指令带来的影响进一步得到减弱。不过可以看出, 调整后的代码在代码量方面有所增加。
(2)使用寄存器变量
CPU 对寄存器的存取要比对内存的存取快得多, 因此为变量分配一个寄存器, 将有助于代码的优化和运行效率的提高。整型、指针、浮点等类型的变量都可以分配寄存器; 一个结构的部分或者全部也可以分配寄存器。给循环体中需要频繁访问的变量分配寄存器也能在
一定程度上提高程序效率。
1.3 指令集相关的优化方法
有时可以利用arm7 指令集的特点对程序进行优化。
(1)避免除法
arm 7 指令集中没有除法指令,其除法是通过调用C 库函数实现的。一个32 位的除法通常需要20~140 个时钟周期。因此, 除法成了一个程序效率的瓶颈, 应尽量避免使用。有些除法可用乘法代替,例如: if ( (x / y) > z)可变通为 if ( x > (y � z)) 。在能满足精度,且存储器空间
冗余的情况下, 也可考虑使用查表法代替除法。当除数为2 的幂次方时, 应用移位操作代替除法。
(2)利用条件执行
arm 指令集的一个重要特征就是所有的指令均可包含一个可选的条件码。当程序状态寄存器(PSR )中的条件码标志满足指定条件时, 带条件码的指令才能执行。利用条件执行通常可以省去单独的判断指令,因而可以减小代码尺寸并提高程序效率。
(3)使用合适的变量类型
arm 指令集支持有符号/ 无符号的8 位、16 位、32位整型及浮点型变量。恰当的使用变量的类型,不仅可以节省代码,并且可以提高代码运行效率。应该尽可能地避免使用char、short 型的局部变量,因为操作8 位/16 位局部变量往往比操作3 2 位变量需要更多指令, 请对比下列3 个函数和它们的汇编代码。