类型转换是否消耗额外的CPU周期?

Does typecasting consume extra CPU cycles

本文关键字:CPU 周期 是否 类型转换      更新时间:2023-10-16

C/c++中的类型转换会导致额外的CPU周期吗?

我的理解是至少在某些情况下应该消耗额外的CPU周期。比如从浮点型到整数型的类型转换,CPU应该要求将浮点型结构转换为整数。

float a=2.0;
int b= (float)a;

我想了解它会/不会消耗额外的CPU周期的情况。

我想说的是"类型之间的转换"是我们应该关注的,而不是是否存在强制转换。例如

 int a = 10;
 float b = a; 

相同
 int a = 10;
 float b = (float)a;

这也适用于改变一个类型的大小,例如

 char c = 'a';
 int b = c; 

这将"将c从单个字节扩展到int大小[使用C意义上的字节,而不是8位意义上的字节]",这可能会在数据移动本身之上和之外添加额外的指令(或所使用的指令的额外时钟周期)。

请注意,有时这些转换并不明显。在x86-64上,一个典型的例子是在数组中使用int而不是unsigned int作为索引。由于指针是64位的,因此需要将索引转换为64位。在unsigned的情况下,这是微不足道的—只需使用该值已经存在的64位版本的寄存器,因为32位加载操作将对寄存器的顶部进行零填充。但如果你有int,它可能是阴性的。因此编译器将不得不使用"将此扩展到64位"指令。在基于固定循环计算索引并且所有值都为正的情况下,这通常不是问题,但是如果您调用的函数不清楚参数是正还是负,编译器肯定必须扩展该值。同样,如果函数返回一个用作索引的值。

然而,任何有能力的编译器都不会盲目地添加指令来将自己的类型转换为自己的类型(可能如果优化被关闭,它可能会这样做-但最小的优化应该看到"我们正在从类型X转换为类型X,这并不意味着什么,让我们把它拿走")。

所以,简而言之,上面的例子并没有增加任何额外的惩罚,但确实存在"将数据从一种类型转换为另一种类型确实会给代码增加额外的指令和/或时钟周期"的情况。

它将在改变底层表示的地方消耗循环。因此,如果将float转换为int或反之亦然,它将消耗周期。根据不同的架构类型转换,如intcharlong longint,可能会也可能不会消耗周期(但通常情况下它们会)。指针类型之间的强制转换只有在涉及多重继承时才会消耗循环。

有不同类型的强制转换。针对不同类型的强制转换,c++有不同类型的强制转换操作符。如果我们从这些角度来看,……

如果从一种类型转换为另一种类型,

static_cast通常会有成本,特别是在目标类型与源类型大小不同的情况下。static_cast s有时用于将指针从派生类型强制转换为基类型。这也可能有代价,特别是当派生类有多个基类时。

reinterpret_cast通常没有直接成本。粗略地说,这种类型的强制转换不会改变值,它只是改变了它的解释方式。然而,请注意,这可能有间接成本。如果将指向字节数组的指针重新解释为指向int类型的指针,那么每次对该指针解引用时都可能要付出代价,除非该指针按照平台所期望的那样对齐。

如果你添加或删除constness,

const_cast不应该花费任何成本,因为它主要是对编译器的注释。如果您使用它来添加或删除volatile限定符,那么我想可能会有性能差异,因为它会启用或禁用某些优化。

dynamic_cast用于从基类指针强制转换为派生类指针,它肯定是有代价的,因为它至少必须检查转换是否适当。

当您使用传统的C强制转换时,您实际上只是要求编译器选择更具体的强制转换类型。因此,要弄清楚你的C类型转换是否有成本,你需要弄清楚它实际上是哪种类型的转换。

阅读Agner Fog的手册:
http://www.agner.org/optimize/
1. c++软件优化:Windows、Linux和Mac平台的优化指南
这是一个巨大的PDF文件,但首先你可以看看:

不要将float和double混合使用
14.8浮点数与整数的转换