繁体   English   中英

uint32_t 作为向量索引在 64 位中比 size_t 具有更好的性能

[英]uint32_t as vector index has better performance than size_t in 64-bit

我有一些与此类似的性能关键代码:

void func(std::vector<int>& v, size_t i)
{
  while(i > 0)
  {
    // do something with v[i]
    // compute next i   
  }
}

在我将i的类型从size_t更改为uint32_t后,代码的运行时间减少了 10% 以上。 调用此 function 时,其输入类型始终为size_t 该代码是使用 Clang 以 64 位编译的。 function 被编译器内联在更复杂上下文的多个位置,因此很难比较汇编代码。 有什么一般的想法为什么会发生这种情况?


我做了一些进一步的调查。 首先,当使用uint32_t作为向量索引时,Clang 似乎不能很好地优化代码。 请参见以下示例:

void func(std::vector<int>& v, size_t i)
{
  for(auto j = i; j < v.size(); ++j)
  {
    v[j] = 0;    
  }
}

如果我们将size_t更改为uint32_t ,将生成大量的程序集: https://godbolt.org/z/1qrrrs

至于我的性能关键代码,当使用size_t时,Clang 可以进行更积极的循环展开。 然而,事实证明这种展开的性能更差,可能是由于某些分支没有像预期的那样经常被击中。 我手动做了一些展开,现在size_tuint32_t之间的性能是一样的。

有什么一般的想法为什么会发生这种情况?

  • CPU 上的 32 位操作可能更快
  • 变量大小的变化可能导致堆栈相对于 memory 页面边界的对齐方式不同,和/或由于缓存冲突导致某些特别关键的数据或指令不会丢失,从而导致偶然更改在性能上。

暂无
暂无

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

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