指针转换是否昂贵?

use*_*564 4 c c++ pointers

指针转换被认为是昂贵的?(例如,转换指针/地址需要多少CPU周期),特别是当你必须经常这样做时(例如,只显示频率范围的一个例子,我知道这种特殊情况有更好的方法) :

unsigned long long *x;
/* fill data to x*/

for (int i = 0; i < 1000*1000*1000; i++)
{

    A[i]=foo((unsigned char*)x+i);

};
Run Code Online (Sandbox Code Playgroud)

Pub*_*bby 9

(例如,转换指针/地址需要多少CPU周期)

在大多数机器代码语言中,只有1个"类型"的指针,因此在它们之间进行转换不需要任何费用.请记住,C++类型实际上只存在于编译时.

真正的问题是这种代码可以破坏严格的别名规则.您可以在其他地方阅读更多相关内容,但实际上编译器会通过未定义的行为生成错误的代码,或者被迫做出保守的假设,从而产生较慢的代码.(注意,char*和朋友在某种程度上可以免除未定义的行为部分)

优化器通常必须在存在指针的情况下对变量做出保守的假设.例如,知道变量x的值为5的常量传播过程在分配给另一个变量(例如,*y = 10)后将无法继续使用此信息,因为它可能是*y是别名x.在y =&x之类的赋值之后可能就是这种情况.

作为赋值给*y的效果,x的值也会改变,因此将x为5的信息传播到*y = 10之后的语句可能是错误的(如果*y确实是x的别名) ).但是,如果我们有关于指针的信息,那么常量传播过程可以进行如下查询:can x是*y的别名吗?然后,如果答案为否,则可以安全地传播x = 5.受混叠影响的另一个优化是代码重新排序.如果编译器确定x没有*y的别名,那么使用或更改x值的代码可以在赋值*y = 10之前移动,如果这样可以改善调度或启用更多循环优化.

为了以可预测的方式实现此类优化,C编程语言的ISO标准(包括其较新的C99版本,请参见第6.5节,第7段)指定不同类型的指针引用相同的非法(有一些例外)记忆位置.这个规则被称为"严格别名",有时可以令人印象深刻地提高性能,[1]但是已经知道打破一些其他有效的代码.一些软件项目故意违反C99标准的这一部分.例如,Python 2.x这样做是为了实现引用计数,[2]并且需要对Python 3中的基本对象结构进行更改以实现此优化.Linux内核这样做是因为严格的别名会导致优化内联代码的问题.[3] 在这种情况下,使用gcc编译时,会调用-fno-strict-aliasing选项以防止可能产生意外代码的不需要的优化.[编辑]

http://en.wikipedia.org/wiki/Aliasing_(computing)#Conflicts_with_optimization

什么是严格别名规则?

  • 此代码不会破坏严格的别名规则,因为`unsigned char*`是一个特定的异常(少数几个之一). (3认同)

Mik*_*our 6

在您可能遇到的任何体系结构上,所有指针类型都具有相同的表示形式,因此表示相同地址的不同指针类型之间的转换没有运行时成本.这适用于C中的所有指针转换.

在C++中,一些指针转换有成本,有些则没有:

  • reinterpret_castconst_cast(或等效的C风格的演员表,例如问题中的那个)和转换为或void*将简单地重新解释指针值,没有任何成本.
  • static_cast如果存在多个基类,则指向基类和指向派生类之间的转换(隐式或使用或等效的C样式转换)可能需要向指针值添加固定偏移量.
  • dynamic_cast 将根据指向的对象的动态类型执行非常重要的工作来查找指针值.

从历史上看,一些体系结构(例如PDP-10)对于指针到字节和指向字的指针有不同的表示形式.转换可能会有一些运行时成本.