C/C++ 中的类型转换会导致额外的 CPU 周期吗?
我的理解是,至少在某些情况下应该消耗额外的 CPU 周期。就像从浮点类型转换为整数一样,CPU 需要将浮点结构转换为整数。
float a=2.0;
int b= (float)a;
我想了解它会/不会消耗额外 CPU 周期的情况。
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
for 索引。由于指针是 64 位的,因此需要将索引转换为 64 位。在无符号的情况下,这很简单——只需使用值已经存在的寄存器的 64 位版本,因为 32 位加载操作会将寄存器的顶部填充为零。但如果你有一个int
,它可能是负数。因此编译器将不得不使用“符号将此扩展到 64 位”指令。这通常不是基于固定循环计算索引并且所有值都是正数的问题,但是如果您调用一个不清楚参数是正数还是负数的函数,编译器肯定会扩展该值. 同样,如果一个函数返回一个用作索引的值。
但是,任何相当称职的编译器都不会盲目地添加指令以将某些东西从其自己的类型转换为自身(如果关闭优化,它可能会这样做 - 但最小优化应该看到“我们正在从类型 X 转换为类型 X,这并不意味着什么,让我们把它拿走”)。
所以,简而言之,上面的例子并没有增加任何额外的惩罚,但肯定存在“将数据从一种类型转换为另一种类型确实为代码添加额外的指令和/或时钟周期”的情况。
它将消耗改变底层表示的周期。float
因此,如果您将 a 转换为aint
或反之亦然,它将消耗周期。取决于架构类型,例如int
tochar
或long long
toint
可能会或可能不会消耗周期(但通常它们会)。如果涉及多重继承,则指针类型之间的转换只会消耗周期。
有不同类型的演员表。对于不同类型的强制转换,C++ 有不同类型的强制转换运算符。如果我们从这些角度来看,...
static_cast
如果您从一种类型转换为另一种类型,通常会产生成本,尤其是在目标类型与源类型的大小不同时。 static_cast
s 有时用于将指针从派生类型转换为基类型。这也可能有成本,特别是如果派生类有多个基类。
reinterpret_cast
通常不会有直接成本。粗略地说,这种类型的转换不会改变值,它只会改变它的解释方式。但是请注意,这可能会产生间接成本。如果您将指向字节数组的指针重新解释为指向 int 的指针,那么每次取消引用该指针时都可能会付出代价,除非该指针按照平台的预期对齐。
const_cast
如果您要添加或删除 constness,则不应花费任何费用,因为它主要是编译器的注释。如果您使用它来添加或删除 volatile 限定符,那么我想可能存在性能差异,因为它会启用或禁用某些优化。
dynamic_cast
,用于从指向基类的指针转换为指向派生类的指针,肯定有成本,因为它必须 - 至少 - 检查转换是否合适。
当您使用传统的 C 转换时,您实际上只是要求编译器选择更具体的转换类型。所以要弄清楚你的 C 演员是否有成本,你需要弄清楚它到底是什么类型的演员。
DL 并享受 Agner Fog 的手册:
http
://www.agner.org/optimize/
1.用 C++ 优化软件:Windows、Linux 和 Mac 平台的优化指南
它是一个巨大的 PDF,但首先你可以查看:
14.7 不要混用 float 和 double
14.8 浮点数和整数之间的转换