繁体   English   中英

通过大量取消引用来优化C代码

[英]Optimizing C code with lots of dereferences

Linux perf和GPerfTools pprof在这段代码中给了我很多停滞的前端和后端周期:

for(j = oL; j < oR; j++) {
   T[j].v = (T[j].x / div)*K+T[j].y /div;
   T[j].x = T[j].x % div;
   T[j].y = T[j].y % div;        
   counterK[T[j].k]++;
  }

给我:

 9.973.660.617 stalled-cycles-frontend   #   42,16% frontend cycles idle   
 4.874.722.502 stalled-cycles-backend    #   20,60% backend  cycles idle   

我了解到停顿的周期意味着指令流水线无法真正前进,无法(可能)等待内存中的某些数据。 我可以看到在那段代码中有很多解引用Pouner来构造成员的方法,这可能是个问题,但是我恐怕我缺乏足够的知识来查看那里的任何优化。 有人可以帮忙吗?

在现代体系结构上,单独取消引用struct指针应该不是问题。 他们可以进行相对寻址并很好地应对此类访问。 同样,在一条评论中提到的混叠也不应该成为问题。 *T*counterK具有不同的类型,因此C永远不会假设它们是别名。

通常,对于您向我们展示的循环,处理器/内存带宽是瓶颈,而不是处理器的速度。 可能是,您正处于可以提供服务的极限。

您正在按顺序访问T ,这已经是您可以做到的最好的选择。 T唯一可能的优化是,您在其中有很多字段,这些字段没有显示给我们的循环使用。 然后,您可能会浪费处理器/内存带宽。 然后将内容压缩为仅包含所需信息的数组可能会有所帮助。

对于counterK事情要复杂得多,因为您使用的信息没有提示访问模式或数组的大小。 如果counterK很大(比您的L1缓存大得多),并且您的访问非常不规则,则可能来自此处。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM