首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C代码分析

C代码分析
EN

Stack Overflow用户
提问于 2010-10-01 17:54:35
回答 4查看 283关注 0票数 2

下面是我在64位linux机器上编写的函数。

代码语言:javascript
复制
void myfunc(unsigned char* arr) //array of 8 bytes is passed by reference
{
   unsigned long a = 0; //8 bytes
   unsigned char* LL = (unsigned char*) &a;

   LL[0] = arr[6];
   LL[1] = arr[3];
   LL[2] = arr[1];
   LL[3] = arr[7];
   LL[4] = arr[5];
   LL[5] = arr[4];
   LL[6] = arr[0];
   LL[7] = arr[2];
}

现在我的问题是:

  1. 变量'a‘会被存储在寄存器中,这样就不会从RAM或chache中一次又一次地访问它了吗?
  2. 在64位架构上工作时,我是否应该假设“arr”数组将存储在寄存器中,因为函数参数存储在64位arch中的寄存器中?
  3. 指针类型转换的效率有多高?我猜这应该是低效的吗?

任何帮助都是徒劳无功。

问候

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2010-10-01 18:08:51

  1. a不能存储在寄存器中,因为您已经获取了它的地址。(valdo正确地指出,真正聪明的编译器可以将数组访问优化为位操作,并将a保留在寄存器中,但我从未见过编译器这样做,我不确定它最终会变得更快)。
  2. arr (指针本身)存储在寄存器中(%edi,在amd64上)。数组的内容在内存中。
  3. 指针类型转换本身通常根本不生成任何代码。但是,使用类型转换做一些愚蠢的事情可能会导致非常低效率的代码,甚至导致行为未定义的代码。

看起来,您正在尝试改变数组中的字节,然后将它们推入一个数字中,而您的示例生成的机器代码对此并没有太大的影响。David建议使用shift和掩码操作是好的(如果您的代码需要在大端机器上运行的话,这也可以避免问题),还有SSE向量置换指令,但我听说使用它们有点麻烦。

顺便说一句,您应该将示例函数的返回类型设置为unsigned long,并将return a;放在最末尾;然后您可以使用gcc -O2 -S,并查看从编译中得到的确切结果。不改变返回a,GCC将愉快地优化整个身体的功能,因为它没有外部可见的副作用。

票数 3
EN

Stack Overflow用户

发布于 2010-10-01 18:08:16

您可能会更好地使用显式shift和掩码指令来实现这一点,而不是使用数组索引。

数组操作将使编译器更难使用寄存器,因为通常不会有诸如“从寄存器A的第3字节加载8位”之类的指令。(优化的编译器可能会发现,使用移位/掩码可以做到这一点,但我不确定这有多大的可能性)。

票数 2
EN

Stack Overflow用户

发布于 2010-10-01 18:13:34

  1. 关于变量a是否将存储在寄存器中的问题是一个优化问题。因为没有volatile修饰符,所以智能编译器会这样做。
  2. 这是个电话会议的问题。如果按照约定,在寄存器中传输单个指针参数,那么arr也是如此。
  3. 指针类型转换不是CPU解释的操作。没有为它生成代码。这只是编译器的信息,你的意思是什么。

(实际上有时转换确实会产生额外的代码,但这与多重继承和多态有关)

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3841812

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档