我是否应该在C ++代码中使用较小类型的int(int8和int16)? [英] Should I prefer to use small types of int (int8 and int16) in C++ code?

查看:88
本文介绍了我是否应该在C ++代码中使用较小类型的int(int8和int16)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在为嵌入式Linux开发C ++/Qt项目,在该项目中,我们不断挑战"处理器的局限性,特别是在更新用户界面中的图形时.由于这些限制(特别是我们前些时候情况变得更糟时的情况),我会在可能的情况下,并且在优化成本最小的情况下,尝试始终对代码进行优化.我正在做的此类优化之一是针对我正在处理的情况始终使用正确的整数值:qint8,qint16和qint32,具体取决于我需要的值有多大.

但是不久前,我读到某处文章,而不是在可能的情况下不尝试使用整数的最小大小,我应该总是更喜欢使用与我的处理器容量有关的整数值,也就是说,如果我的处理器是32-面向位,那么即使不需要这么大的整数,我也应该始终使用qint32.在一开始我不明白为什么,但是

我不相信.首先,没有提供任何实际参考资料来证实这一论点:我只是不明白为什么从32位内存空间进行写入和读取会比使用32位整数进行写入慢(为什么给出的解释不是很容易理解), 顺便提一句).其次,当我需要将数据从一侧传输到另一侧时,例如使用Qt的信号和插槽机制时,我的应用程序上会有一些时刻.由于我是将数据从一个点传输到另一点,难道较小的数据总不能比较大的数据有改善吗?我的意思是发送两个字符(不是通过引用)的信号不应该比发送两个32位整数更快地完成工作?

实际上,尽管处理器说明"建议使用处理器的特性,但其他情况则相反.例如,在处理数据库时,线程均表明存在优势(即使只是在某些情况下)使用较小版本的整数.

那么,毕竟,在上下文允许或不允许的情况下,我应该更喜欢使用小类型的int吗?还是有一个案例列表,其中一种方法或另一种方法更可能给出更好或最差的结果?(例如,在使用数据库时,我应该使用int8和int16,但在所有其他情况下,我应该使用处理器的默认类型)

最后一个问题:Qt通常具有基于int的函数实现.在这种情况下,强制转换操作不会消除使用较小整数可能带来的任何可能的改进吗?

解决方案

这个问题确实太广泛了,没有指定特定的CPU.由于某些32位CPU具有处理较小类型指令的大量指令,因此有些指令则没有.一些32位CPU可以平稳地处理未对齐的访问,一些CPU会因此而产生较慢的代码,还有一些CPU遇到这种情况会暂停并着火.


也就是说,首先在每个C和C ++程序中都有标准整数提升的情况,这将隐式将您使用的所有小整数类型转换为 int .

只要结果与未优化的代码相同,编译器就可以自由使用标准中指定的整数提升或对其进行优化,以最有效的代码为准.

如果程序员不知道各种隐式类型提升规则是如何工作的,则隐式提升可能会创建更有效的代码,但也会创建带有意外类型和签名更改的细微,灾难性的错误.可悲的是,许多可能的C和C ++程序员却没有.当使用较小的整数类型时,与在各处使用32位大小的变量相比,您需要具有更强的能力/清醒的程序员.

因此,如果您正在阅读此书,但从未听说过整数提升规则通常的算术转换/平衡,那么我会强烈建议您立即停止任何手动优化整数大小的尝试,并阅读遵循这些隐式促销规则.


如果您了解所有隐式升级规则,则可以使用较小的整数类型进行手动优化.但是要使用那些使编译器具有最大灵活性的方法.这些是:

  #include< stdint.h>int_fast8_tint_fast16_tuint_fast8_tuint_fast16_t 

使用这些类型时,如果可以产生更快的代码,则编译器可以自由地将它们更改为更大的类型.

上述变量之间的区别仅在于整数提升/表达式优化,在于使用快速类型,编译器不仅可以确定哪种类型最适合给定计算的CPU寄存器,还可以确定何时使用内存和对齐方式变量已分配.

I'm working in a C++/Qt project for Embedded Linux where we are constantly "duelling" against the limitations of our processor specially when it comes to updating the graphs in the user interface. Thanks to those limitations (and specially our situation some time ago when things were even worse), I try to optimize the code always when I can and if the costs of optimization are minimum. One of such optimizations I was doing is to always use the correct integer value for the situation I'm handling: qint8, qint16 and qint32 depending on how big is the value I need.

But some time ago I read somewhere that instead of trying to use the minimal size of integer when possible, I should always prefer to use the integer value related to the capacity of my processor, that is, if my processor is 32-bit oriented, then I should prefer to use qint32 always even when such a big integer wasn't required. In a first moment I couldn't understand why, but the answer to this question suggest that is because the performance of the processor is greater when it has to work with its "default size of integer".

Well I'm not convinced. First of all no actual reference was provided confirming such a thesis: I just can't understand why writing and reading from a 32-bit memory space would be slower then doing it with 32 bit integer (and the explanation given wasn't much comprehensible, btw). Second there are some moments on my app when I need to transfer data from one side to the other such as when using Qt's signals and slots mechanism. Since I'm transferring data from one point to the other shouldn't smaller data always give an improvement over bigger data? I mean a signal sending two chars (not by reference) isn't supposed to do the work quicker then sending two 32 bit integers?

In fact, while the "processor explanation" suggests using the characteristics of your processor, other cases suggests the opposite. For example, when dealing with databases, this and this threads both suggests that there is an advantage (even if just in some cases) in using smaller versions of integer.

So, after all, should I prefer to use small types of int when the context allows or not? Or is there a list of cases when one approach or the other is more likely to give better or worst results? (e.g. I should use int8 and int16 when using databases but the default type of my processor in all other situations)

And as a last question: Qt normally have int-based implemenations of its functions. In such cases, doesn't the cast operation annihilates any possible improvement that one could have by using minor integers?

解决方案

This question is really too broad without specifying a specific CPU. Because some 32 bit CPUs have plenty of instructions for handling smaller types, some don't. Some 32 bit CPUs handle misaligned access smoothly, some produce slower code because of it, and some halt and catch fire when they encounter it.


That being said, first of all there is the case of standard integer promotion present in every C and C++ program, which will implicitly convert all small integer types you use into int.

The compiler is free to use integer promotion as specified in the standard, or to optimize it away, whichever leads to the most effective code, as long as the results are the same as for non-optimized code.

Implicit promotion may create more effective code but it may also create subtle, disastrous bugs with unexpected type and signedness changes, if the programmer is not aware of how the various implicit type promotion rules work. Sadly, plenty of would-be C and C++ programmers are not. When using smaller integer types, you need to be a much more competent/awake programmer than if you just use 32 bit sized variables all over the place.

So if you are reading this but have never heard of the integer promotion rules or the usual arithmetic conversions/balancing, then I would strongly suggest that you immediately stop any attempt of manually optimizing integer sizes and go read up on those implicit promotion rules instead.


If you are aware of all implicit promotion rules, then you can do manual optimization by using smaller integer types. But use the ones which gives the compiler most flexibility. Those are:

#include <stdint.h>

int_fast8_t
int_fast16_t
uint_fast8_t
uint_fast16_t

When these types are used, the compiler is free to change them for a larger type if that would yield faster code.

The difference between the above variables just relying on integer promotion/expression optimization, is that with the fast types the compiler can not only decide which type suits the CPU registers best for a given calculation, but also decide memory consumption and alignment when the variables are allocated.

这篇关于我是否应该在C ++代码中使用较小类型的int(int8和int16)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆