类型转换会消耗额外的CPU周期

时间:2013-05-14 09:21:05

标签: c++ c performance

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

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

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

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

4 个答案:

答案 0 :(得分:23)

我想说“在不同类型之间转换”是我们应该关注的,而不是是否有演员。例如

 int a = 10;
 float b = a; 

将与:

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

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

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

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

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

然而,任何合理称职的编译器都不会盲目地添加指令以将某些东西从它自己的类型转换为自身(可能如果关闭了优化,它可能会这样做 - 但是最小化优化应该看到“我们正在从类型X转换为类型X,这并不意味着什么,让我们把它拿走“)。

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

答案 1 :(得分:13)

它会消耗改变底层表示的周期。因此,如果您将float转换为int,反之亦然,则会消耗周期。取决于体系结构演员,例如intcharlong longint可能会或可能不会消耗周期(但通常会消耗周期)。如果涉及多个继承,则指针类型之间的转换将仅消耗周期。

答案 2 :(得分:8)

有不同类型的演员阵容。对于不同类型的强制类型,C ++有不同类型的强制转换运算符。如果我们用这些术语来看待它,......

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

static_cast通常会有成本,特别是如果目标类型的大小与源类型不同。 static_cast有时用于将派生类型的指针强制转换为基类型。这也可能有成本,特别是如果派生类有多个基数。

reinterpret_cast通常没有直接费用。松散地说,这种类型的演员表并没有改变价值,只是改变了它的解释方式。但请注意,这可能会产生间接成本。如果您将指向字节数组的指针重新解释为指向int的指针,那么每次取消引用该指针时都可能需要支付一笔费用,除非指针按照平台的预期进行对齐。

如果你要添加或删除constness,

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

dynamic_cast,用于从指向基类的指针转换为指向派生类的指针,大多数情况下都有成本,因为它必须 - 至少 - 检查转换是否为合适的。

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

答案 3 :(得分:3)

DL并享受Agner Fog的手册:
http://www.agner.org/optimize/
1. 使用C ++优化软件:适用于Windows,Linux和Mac平台的优化指南
这是一个巨大的PDF,但一开始你可以看看:

  14.7不要混合浮动和双重   14.8浮点数和整数之间的转换