通过良好的设计减少缓存未命中 如何减少C++程序设计时可能出现的缓存缺失数?

通过良好的设计减少缓存未命中 如何减少C++程序设计时可能出现的缓存缺失数?,c++,caching,inline,C++,Caching,Inline,内联函数每次都有用吗?还是只有当程序有CPU限制(即程序面向计算而不是面向i/O)时才好?允许CPU高效地预取数据。例如,您可以按行而不是按列、展开循环等减少处理多维数组时的缓存未命中数 这种优化取决于硬件体系结构,因此最好使用某种特定于平台的探查器(如“英特尔VTune”)来检测缓存可能出现的问题。用于数据绑定操作 在列表、地图和集合上使用数组和向量 按行逐列处理 避免在不必要时使用动态内存。使用new、delete、智能指针等,往往会将程序数据分散到内存中。那不好。如果可以将大部分数据保存在

内联函数每次都有用吗?还是只有当程序有CPU限制(即程序面向计算而不是面向i/O)时才好?

允许CPU高效地预取数据。例如,您可以按行而不是按列、展开循环等减少处理多维数组时的缓存未命中数


这种优化取决于硬件体系结构,因此最好使用某种特定于平台的探查器(如“英特尔VTune”)来检测缓存可能出现的问题。

用于数据绑定操作

  • 在列表、地图和集合上使用数组和向量

  • 按行逐列处理


  • 避免在不必要时使用动态内存。使用new、delete、智能指针等,往往会将程序数据分散到内存中。那不好。如果可以将大部分数据保存在一起(例如,通过在堆栈上声明对象),那么缓存肯定会工作得更好。

    内联函数的运行可能会损害指令缓存。而且,如果内存不是fetch绑定的,那么它就不太可能产生太大的差异(如果有的话)

    和往常一样,任何优化都应该通过分析而不是直觉来进行。更不用说,您需要了解分析器告诉您的内容,这意味着您熟悉汇编语言以及您正在优化的plaftorm的特定特性


    现在有点老了,但是迈克·艾布拉什的《图形编程黑皮书》仍然有很多好的建议
    • 考虑您是想要“数组的结构”还是“结构的数组”。您要使用的内容将取决于数据的每个部分
    • 尝试将结构保持为32字节的倍数,以便它们均匀地打包缓存线
    • 将数据划分为热元素和冷元素。如果你有一个O类对象数组,你经常使用O.X,O.Y,O.Z,但只是偶尔需要访问O.I,O.J,O.K,然后考虑把O.X,O.Y和O.Z放在一起,把I,J和K部分移到一个并行的腋下数据结构。
    • 如果您有多维数据数组,那么使用通常的行顺序布局,沿着首选维度扫描时,访问速度将非常快,而沿着其他维度扫描时,访问速度将非常慢。相反,将其映射到一个维度将有助于在任何维度中遍历时平衡访问速度。(阻塞技术与此类似——它们只是Z阶,基数更大。)
    • 如果您必须导致缓存丢失,那么尝试尽可能多地使用该数据以分摊成本
    • 你在做什么多线程的事情吗?注意缓存一致性协议的速度减慢。填充标志和小计数器,以便它们位于单独的缓存线上
    • 如果您提前知道要访问的内容,Intel上的SSE将提供一些预取内部函数

    如果你做C++和多线程,你需要考虑错误的共享、局部性和每个处理器的缓存上的数据的热度。这会有很大的不同。特别是在多线程计算中,后进先出方式比先进先出方式更有效,但在单处理器体系结构中也是有效的

    萨特说得很好。这里有幻灯片,视频旁边有幻灯片很好,因为它的质量有点糟糕。视频链接和演示幻灯片已失效。建议编辑评论和答案,包括视频标题,以便人们可以找到它。+1。希尔伯特曲线的想法很新颖,你从哪里想到的?在hilbert曲线坐标和标准数组坐标之间来回转换所需的时间真的值得缓存效率吗?或者,可能只值得在一个方向进行坐标转换,而不是在另一个方向进行坐标转换吗?