为什么int是MSP430-GCC中的小整数的优先级而不是(无符号)char

9 c microcontroller assembly msp430 mspgcc

在msgpcc(GSP for MSP430微控制器)手册中,作者写道:

如果要在函数中使用小整数,请使用int而不是char或unsigned char.生成的代码将更有效,并且在大多数情况下,实际上不会浪费存储.

为什么int效率更高?

UPD.为什么(u)int_fast8_t在mspgcc中定义(unsigned) char,而不是(unsigned) int.据我所知,(u)int_fast*_t应该定义为具有足够大小的最有效类型.

小智 5

一般的经验法则是,CPU在其原始字大小的整数上运行速度最快.

这当然完全取决于架构,请参阅此类似问题的答案,以获得有关该点的更多说明.


bbl*_*coe 5

TI已针对其Tiva-C(正式Stellaris)MCU发布了有关该主题的应用笔记.

在"简介"部分中,表格提供了影响性能和大小的因素列表.一个因素标签可变大小的规定," 使用非最佳小变量可能意味着额外的指令签名或unsign扩展...... ".

此外,在"变量大小"一节中,它指出:

"当局部变量小于寄存器大小时,通常需要额外的代码.在Stellaris部分,这意味着大小为byte和halfword(分别为char和short int)的局部变量需要额外的代码. 8位或16位微控制器可能已将本地转换为较小的尺寸(以避免太大的问题),这意味着此类代码将运行得更慢并占用更多的代码空间."

请参阅:http://www.ti.com/lit/an/spma014/spma014.pdf

以下内容由编译器处理,但仍与手头的问题有关:

MSP430是一款16位微处理器.char只有8位,需要打包以确保所有单词都对齐.例如,3个字符在内存中无法正确对齐.相反,使用16位的整数并始终对齐.

当您使用16的倍数(例如16和32)的可变大小时,您还可以更有效地利用内存.您最终不会使用填充来对齐内存.


old*_*mer 4

一般来说,不一定特定于该处理器,它与符号扩展和屏蔽有关,需要额外的指令才能忠实地实现 C 源代码。16 位、32 位或 64 位处理器中的带符号 8 位值可能涉及额外的符号扩展指令。32 位处理器上的 8 位添加可能涉及到 0xFF 等的额外指令。

你应该做一些简单的实验,这需要几次迭代,但我很快就发现了一些显示出差异的东西。

unsigned int fun ( unsigned int a, unsigned int b )
{
    return(a+b)<<3;
}

unsigned char bfun ( unsigned char a, unsigned char b )
{
    return(a+b)<<3;
}


 int sfun (  int a,  int b )
{
    return(a+b)<<3;
}

 char sbfun (  char a,  char b )
{
    return(a+b)<<3;
}
Run Code Online (Sandbox Code Playgroud)

产生

00000000 <fun>:
   0:   0f 5e           add r14,    r15 
   2:   0f 5f           rla r15     
   4:   0f 5f           rla r15     
   6:   0f 5f           rla r15     
   8:   30 41           ret         

0000000a <bfun>:
   a:   4f 5e           add.b   r14,    r15 
   c:   4f 5f           rla.b   r15     
   e:   4f 5f           rla.b   r15     
  10:   4f 5f           rla.b   r15     
  12:   30 41           ret         

00000014 <sfun>:
  14:   0f 5e           add r14,    r15 
  16:   0f 5f           rla r15     
  18:   0f 5f           rla r15     
  1a:   0f 5f           rla r15     
  1c:   30 41           ret         

0000001e <sbfun>:
  1e:   8f 11           sxt r15     
  20:   8e 11           sxt r14     
  22:   0f 5e           add r14,    r15 
  24:   0f 5f           rla r15     
  26:   0f 5f           rla r15     
  28:   0f 5f           rla r15     
  2a:   4f 4f           mov.b   r15,    r15 
  2c:   30 41           ret         
Run Code Online (Sandbox Code Playgroud)

msp430 具有字和字节版本的指令,因此简单的加法或减法不必执行您在使用小于寄存器大小的变量时所期望的剪切或符号扩展。作为一名程序员,我们可能知道我们只会向 sbfun 提供一些非常小的数字,但编译器不会,并且必须忠实地实现我们编写的代码,在 sfun 和 sbfun 之间生成更多代码。使用不同的编译器和处理器进行这些实验以查看其实际效果并不难,唯一的技巧是创建处理器没有简单指令来解决的代码。

另一个例子

unsigned int fun ( unsigned int a, unsigned int b )
{
    return(a+b)>>1;
}

unsigned char bfun ( unsigned char a, unsigned char b )
{
    return(a+b)>>1;
}
Run Code Online (Sandbox Code Playgroud)

产生

00000000 <fun>:
   0:   0f 5e           add r14,    r15 
   2:   12 c3           clrc            
   4:   0f 10           rrc r15     
   6:   30 41           ret         

00000008 <bfun>:
   8:   4f 4f           mov.b   r15,    r15 
   a:   4e 4e           mov.b   r14,    r14 
   c:   0f 5e           add r14,    r15 
   e:   0f 11           rra r15     
  10:   4f 4f           mov.b   r15,    r15 
  12:   30 41           ret         
Run Code Online (Sandbox Code Playgroud)