C++ 我是否应该在C+中使用小型int(int8和int16)+;密码?

C++ 我是否应该在C+中使用小型int(int8和int16)+;密码?,c++,performance,qt,integer,embedded,C++,Performance,Qt,Integer,Embedded,我在一个嵌入式Linux的C++/Qt项目中工作,在这个项目中,我们不断地与处理器的限制进行“决斗”,特别是在更新用户界面中的图形时。由于这些限制(特别是我们前一段时间的情况,当时情况更糟),如果优化成本最低,我总是尽可能地优化代码。我所做的其中一个优化就是在我处理的情况下始终使用正确的整数值:qint8、qint16和qint32,这取决于我需要的值有多大 但不久前,我在某个地方读到,与其尽可能使用整数的最小大小,我应该总是更喜欢使用与处理器容量相关的整数值,也就是说,如果我的处理器是32位的

我在一个嵌入式Linux的C++/Qt项目中工作,在这个项目中,我们不断地与处理器的限制进行“决斗”,特别是在更新用户界面中的图形时。由于这些限制(特别是我们前一段时间的情况,当时情况更糟),如果优化成本最低,我总是尽可能地优化代码。我所做的其中一个优化就是在我处理的情况下始终使用正确的整数值:qint8、qint16和qint32,这取决于我需要的值有多大

但不久前,我在某个地方读到,与其尽可能使用整数的最小大小,我应该总是更喜欢使用与处理器容量相关的整数值,也就是说,如果我的处理器是32位的,那么我应该更喜欢总是使用qint32,即使不需要这么大的整数。首先,我不明白为什么,但我认为这是因为当处理器必须使用其“默认整数大小”时,处理器的性能更高

我不相信。首先,没有提供实际的参考资料来证实这样一个论点:我只是不明白为什么从32位内存空间进行写和读会比使用32位整数慢(顺便说一句,给出的解释不太容易理解)。其次,在我的应用程序中,有时我需要将数据从一端传输到另一端,比如使用Qt的信号和插槽机制。既然我将数据从一个点传输到另一个点,那么较小的数据不应该总是比较大的数据更好吗?我的意思是,发送两个字符(不是通过引用)的信号不应该比发送两个32位整数更快吗

事实上,虽然“处理器解释”建议使用处理器的特性,但其他情况则相反。例如,在处理数据库时,和线程都表明使用更小版本的integer有一个优势(即使只是在某些情况下)

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


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

有关整数提升的信息:

小整数类型(如char)的PRV值可以转换为 较大整数类型(如int)的值。特别地, 算术运算符不接受小于int的类型作为 参数和积分升级将在 左值到右值的转换(如果适用)。这种转换总是 保留该值


通常,始终使用
int
的概念适用于临时值(如循环变量),因为对于许多操作或库调用,它可能被提升为int

在存储大量数据时,尤其是在数组中,使用较小的类型要好得多。问题是,有多少人是大的,不幸的是,这是情境性的

当你可以免费使用完整的
int
时,结构填充也会给你一些回旋的空间。例如,如果有3个
short
s,最常用的可能是
int
。另外,您应该按大小对成员进行排序,以避免由于填充而产生不必要的间隙


不幸的答案是测试,特别是如果您使用的是资源受限的环境,如嵌入式Linux。有时它会值得空间,有时它不会

反对使用小变量的一个有力论据是,当映射到寄存器(假设它们没有隐式展开)时,如果ISA使用部分寄存器,它们可能会导致意外的错误依赖关系。x86就是这种情况,因为一些旧程序仍然使用AH或AX及其对应程序作为8/16位大小的寄存器。如果寄存器的上半部分有一些值(由于之前写入完整寄存器),CPU可能会被迫携带该值,并将其与您计算的任何部分值合并以保持正确性,从而导致串行依赖链,即使您的计算是独立的

您链接的答案提出的内存声明也成立,尽管我发现它有点弱-内存子系统通常在完全缓存线粒度下工作(现在通常是64字节),然后旋转和屏蔽,但这本身不应该对性能造成影响——如果有什么影响的话,那就是当数据访问模式显示出空间位置时,它可以提高性能。在某些情况下,较小的变量可能也会增加导致对齐问题的风险,特别是如果将不同大小的变量紧密打包,但大多数编译器应该更清楚这一点(除非明确强制不这样做)


我认为内存上的小变量的主要问题是——增加了错误依赖性的可能性——合并是由内存系统隐式完成的,但是如果其他内核(或套接字)共享您的一些变量,您就有可能将整行从缓存中删除)

一般来说,过早优化没有什么用处。对于局部变量和较小的类和结构,使用非本机类型几乎没有好处。根据过程调用标准,将较小的类型打包/解包到单个寄存器中可能会添加比字号类型成本更多的代码

但是,对于较大的阵列,可以使用列表/树节点(IOW:较大的数据结构)
#include <stdint.h>

int_fast8_t
int_fast16_t
uint_fast8_t
uint_fast16_t