在 16 位微处理器上,我应该使用 Short 数据类型而不是 int 吗?
我读过,使用 short
与 int
实际上会导致编译器效率低下,因为它需要使用 int
数据类型,无论是因为C 整数提升。对于 16 位微处理器来说是这样吗?
另一个问题:如果我有一个 1 和 0 的数组,在这个 16 位微处理器中使用 uint8_t 或 unsigned char 是否最有效?或者将其转换回 int 是否仍然存在问题。
请帮我解决我脑海中这个混乱的问题。谢谢!
I've read that using short
vs int
is actually creating an inefficiency for the compiler in that it needs to use the int
datatype regardless because of C integer promotion. Is this true for 16-bit microprocessors?
Another question: If I have an array of 1s and 0s, is it most efficient to use uint8_t
or the unsigned char
in this 16-bit microprocessor? Or is there still an issue with it being converted back to int..
Please help me clear up this muddy issue in my mind. Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
这真的是一个问题吗?在我听说过的大多数 16 位系统上,
int
和short
最终大小相同(16 位),因此在实践中应该没有什么区别.如果系统上存在
uint8_t
,它将与unsigned char
同义。unsigned char
将是系统上可用的最小无符号类型。如果超过 8 位,则不会有uint8_t
。如果少于 8 位,则违反标准。不会有效率差异,因为一个必须根据另一个来定义。最后,您真的需要担心这些微观差异吗?如果这样做,您将需要查看程序集输出或(更有可能)配置文件,看看哪一个更快。
Is it really an issue? On most 16 bit systems I've heard of,
int
andshort
end up being the same size (16 bits), so there shouldn't really be a difference in practice.If
uint8_t
exists on a system, it's going to be synonymous withunsigned char
.unsigned char
will be the smallest unsigned type avaliable on the system. If it's any more than 8 bits, there will be nouint8_t
. If it's less than 8 bits, then it's violating the standard. There will be no efficiency difference since one has to be defined in terms of the other.Lastly, do you really need to worry about these kind of microscopic differences? If you do you'll need to peek at the assembly output or (more likely) profile and see which one is faster.
在 Blackfin 上,32 位类型还是 16 位类型通常会产生更高的性能可能不是一个简单的答案,因为它支持 16、32 和 64 位指令,并且具有两个 16 位 MAC。这将取决于操作,但我建议您相信您的编译器优化器会做出这样的决定,它比您可能关心的更多地了解处理器的指令计时和调度。
也就是说,在您的编译器中, int 和 Short 在任何情况下都可能具有相同的大小。请查阅文档,或者使用
sizeof
进行测试,或者在limits.h
标头中查找可推断宽度或各种类型的数字范围。如果您确实想限制数据类型大小,请使用
stdint.h
类型,例如int16_t
。stdint.h
还定义了最快的最小宽度整数类型< /a> 例如int_fast16_t
,这将保证最小宽度,但如果它在您的目标上速度更快,则会使用更大的类型。这可能是解决问题的最可移植的方法,但它依赖于实现者对要使用的适当类型做出良好的决定。在大多数架构上,这几乎没有区别,但在 RISC 和 DSP 架构上,情况可能并非如此。也可能并非特定大小在所有情况下都是最快的,对于 Blackfin 来说尤其如此。在某些情况下(大量数据从外部存储器传输到外部存储器的情况),最快的大小可能是与数据总线宽度匹配的大小。
On a Blackfin it is probably not a simple answer whether 32 or 16 bit types will generate higher performance generally since it supports 16, 32 and 64-bit instructions, and has two 16 bit MACs. It will depend on the operations, but I suggest that you trust your compiler optimiser to make such decisions, it knows more about the processor's instruction timing and scheduling than you probably care to.
That said it may be that in your compiler int and short are the same size in any case. Consult the documentation, ot test with
sizeof
, or look in thelimits.h
header for numeric ranges that will infer the widths or the various types.If you truly want to restrict data type size use the
stdint.h
types such asint16_t
.stdint.h
also defines fastest minimum-width integer types such asint_fast16_t
, this will guarantee a minimum width, but will use a larger type if it will be faster on your target. This is the probably the most portable way of solving your problem, but it relies on the implementer to have made good decisions about the appropriate types to use. On most architectures it makes little or no difference, but on RISC and DSP architectures that may not be the case. It may also not be the case that a particular size is fastest in all circumstances, and that is probably especially true in the case of Blackfin.In some cases (where large amounts of data are transferred to an from external memory), the fastest size is likely to be one that matches the data bus width.
在 16 位或更大的处理器上,如果您不关心需要多少存储空间,请使用“int”而不是“short”或“signed char”。如果您不关心存储要求或包装行为,请使用“unsigned int”而不是“unsigned Short”或“unsigned char”。在 8 位处理器上,“char”类型可能比“int”更快,但在 16 位及更大的处理器上,其中 16 位数学比 32 位数学更快,“int”可能是 16 位,因此无需使用“short”或“char”来提高速度。
顺便说一句,在某些处理器上,“unsigned Short”比“unsigned int”慢得多,因为 C 标准要求对无符号类型的操作“换行”。如果无符号短变量“foo”存储在寄存器中,则典型的 ARM 编译器会生成“foo+=1;”的代码将生成一条指令来执行增量操作,并生成两条指令来将值截断为 65535 [顺便说一句,一个注意到“foo”永远不会超过 65536 的优化编译器可以削减一条指令,但我不知道是否有任何真正的编译器会这样做]。带符号的“short”不一定比“带符号的int”慢,因为标准没有强制要求截断;不过,我不确定是否有编译器会跳过有符号类型的截断。
On a 16-bit or larger processor, if you don't care how much storage things will take, use 'int' instead of 'short' or 'signed char'. If you don't care about storage requirements or wrapping behavior, use 'unsigned int' instead of 'unsigned short' or 'unsigned char'. On an 8-bit processor, 'char' types may be faster than 'int', but on 16-bit and larger processors where 16-bit math is faster than 32-bit math, 'int' is likely to be 16 bits so there's no need to use 'short' or 'char' for speed.
BTW, on some processors, 'unsigned short' is much slower than 'unsigned int', because the C standard requires that operations on unsigned types 'wrap'. If unsigned short variable "foo" is stored in a register, a typical ARM compiler generating code for "foo+=1;" would generate one instruction to do the increment, and two instructions to truncate the value to 65535 [BTW, an optimizing compiler that noticed that 'foo' could never exceed 65536 could shave an instruction, but I don't know if any real compilers would]. The signed 'short' would not have to be slower than 'signed int', since no truncation is mandated by the standard; I'm not sure whether any compilers would skip the truncation for signed types, though.
我强调在依赖字节大小的项目中使用如下所示的块:
对于任何合适的数据类型。
任何转换问题都应该在编译时解决。这些将取决于 cpu 和编译器。
当然,在 16 位 CPU 上添加 2 个 32 位数字需要编译器进行一些处理。当您从内存加载时,也可能会发生有趣的事情,具体取决于内存字宽以及是否可以从任何地址加载,或者是否必须从给定边界加载字节
在
short
中,YMMV ,并在分析后进行优化。I make a point of having a block that looks like this in projects that rely on byte sizes:
For whatever datatypes are appropriate.
Any conversion issues should be figured out at compile time. Those will be cpu and compiler dependent.
Of course adding 2 32-bit numbers on a 16-bit CPU will entail some finangling by the compiler. There can also be amusing things when you dink with loading from memory, depending on memory word width and whether you can load from any address, or if bytes have to be loaded from a given boundary
In
short
, YMMV, and optimize after profiling.