扫描std::array,向前与向后
Scanning std::array, forwards vs backwards
我想尽可能快地通过std::数组进行线性扫描。我应该向前(从索引0到索引n)还是向后(从索引n到索引0)扫描,或者这有关系吗?
传统上,建议扫描n到零,因为在大多数架构中,与零相比,循环控制比其他数字更便宜。(正如其他人所指出的,预取缓存可能会也可能不会否定这一优势,这再次取决于体系结构的细节。)
要确定这是否真的会对您的场景产生影响——考虑到您在循环体中所做的事情,这是否是一个重要的差异——以及循环是否会对应用程序的性能产生任何影响——需要对您的特定代码和体系结构进行更多的分析,或者进行一些真实世界的测试。
对于尝试微观优化的人的标准提醒:占运行时1%的东西的无限性能改进需要付出无限的努力,并产生1%的改进。对占运行时10%的东西进行10%的改进,所需的精力要少得多,而且会产生同样的好处不要浪费时间对错误的事情进行微观优化做适当的性能分析并让它指导你——记住,算法或数据结构的改变可能比调整一些指令更有效率。
这在很大程度上取决于实际场景。
这里主要有两件事需要考虑。
首先是循环开销,向后(n
->0
)循环在技术上可能会更快一些。但只有当循环非常紧凑时,这才有意义,也就是说,循环体足够琐碎,并且它的逻辑基本上不受顺序的影响。
另一件事是内存访问,从历史上看,CPU在缓存/预取转发方面会更好,但现在它们在这两方面都做得很好。问题是,这并不是那么简单,因为这将取决于实际的访问模式和CPU。
一个非常非常的一般答案可能是:对于具有非平凡体和足够大的n
的循环,应该几乎没有差异。
但实际的答案是:它很复杂,如果你怀疑它有可能产生任何实质性的性能差异,唯一的方法就是测试它
相关文章:
- C++11 中不同类型的对象的 std::array 的替代方案
- constexpr begin of a std::array
- C++如果必须在编译时确定大小,std::array 有什么意义?
- 标准::unordered_map 中的 std::array 的值初始化
- 确保编译时的特定 std::array 位置
- std::array的长度有大小限制吗?
- 将 std::array 移动到另一个 std::array
- 检查输入 std::array 指针数据是否等于某个常量数组
- 如何读/写或遍历 std::array 中的特定元素范围?
- 是否可以使用 std::array 作为 POD 结构的数据容器?
- 如何在C++中传递一个大小未知的 std::array?
- 将 std::array 推回 std::vector N 次的优雅方式
- 如何在 c++11 中静态断言 std::array 类成员进行排序?
- unqualified sort() -- 为什么它在 std::vector 上使用而不是在 std::array 上
- 按值返回 std::array
- 如何将变量内容常量转换为 std::array 的大小?
- 将初始化器列表/聚合初始化转发到 std::array 成员
- 无法推断类中的类型,构造函数采用 std::array
- 为什么 char 可以在 std::array 中初始化为 nullptr,而不是单独初始化?
- C++ IDE 不会推断/自动完成对模板类中的 std::array 下标表达式的成员访问