通过大量解引用优化C代码

时间:2014-07-21 14:52:02

标签: c optimization

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   

我理解停滞的循环意味着指令管道无法真正前进,等待(可能)来自内存的某些数据。我可以看到在这段代码中有很多解构引用的构造成员,这可能是一个问题,但我担心我缺乏足够的知识来看到那里的任何优化。有人可以帮忙吗?

1 个答案:

答案 0 :(得分:1)

解除引用struct指针本身不应该是现代架构的问题。他们可以做相对寻址并很好地应对这种访问。另外,如一条评论中提到的别名不应该是一个问题。 *T*counterK有不同的类型,因此C永远不会假设它们是别名。

通常,对于这样的循环,因为您向我们展示了处理器/内存带宽是bottelneck而不是处理器的速度。可能是,你正处于你的记忆可以服务的极限。

您正在按顺序访问T,这已经是您可以做的最好的了。 T可能唯一的优化就是你有很多字段,而你正在向我们显示的循环没有使用这些字段。那么你可能会浪费处理器/内存带宽。然后压缩一个只有所需信息的数组中的东西可能会有所帮助。

对于counterK,事情更复杂,因为您提供的信息没有提示访问模式或数组的大小。如果counterK很大(比你的L1缓存大得多)并且你的访问非常不规则,那么这些摊位可能来自这里。