【问题标题】:Locality and code optimization局部性和代码优化
【发布时间】:2012-06-13 22:37:30
【问题描述】:

优化器能否摆脱对空间局部性的不良使用?我正在维护一些其他人编写的代码,他们的许多数组都是以随意的顺序声明的,并且每次调用时都会以不同的方式进行迭代。

由于代码的复杂性,每次循环阵列时都需要大量时间来尝试和重新管理。我在阅读汇编语言方面不够熟练,无法准确判断不同优化级别的不同之处,但我的问题是,

在编写程序时,局部性很重要,还是优化后我就不用担心了?

【问题讨论】:

    标签: optimization gcc assembly spatial


    【解决方案1】:

    正确设置局部性很重要,因为它可以在运行时产生两个数量级的差异(如果出现页面错误,则为 5-6 个数量级)。

    除了 真实的 编译器通常不会自动处理这个事实(正如 Joel Falcou 所说),即使是 假设的 编译器也很难做到这一点一个东西。在很多情况下,编译器做这样的事情甚至可能是无效的,并且很难预测什么时候是,什么时候不是。

    例如,您有在 CPU 上计算的顶点数据,并将其上传到 OpenGL 或 DirectX 等图形 API。您已经同意该 API 的某个顶点数据布局。现在编译器认为以某种方式重新排列布局更有效。砰,你死定了。
    编译器应该怎么知道?

    假设你有几个数组和几个指针,一些指针给其他指针起别名,或者一些指针由于某种原因指向数组的中间,另一些指针指向开头。编译器认为以不同的顺序执行某些操作会更有效,用另一个结果覆盖一个结果。
    撇开数据损坏问题不谈,假设这些数组“有点大”,所以它们肯定会被动态分配而不是在堆栈上。这意味着从编译器的角度来看,它们的起始地址是“不确定的”甚至是“随机的”。编译器将如何做出决定——在编译时——不知道一半的细节?

    【讨论】:

    • 好点。 (不是我的情况),但为了争论,静态大小的数组呢?既然会有更多的模式,那么编译器是否能够剔除那个模式? (我的项目不需要,只是一个好奇的问题)
    • 再一次,对于现有的编译器,这是一个明确的“不”。 假设的编译器原则上可以做这样的事情,只要它符合语言规范,并且只要外部可观察的行为是 100% 相同的。然而,这仍然是一个难题。编译器应该如何处理多线程?通常这是编译器不关心(也不需要)的事情,因为程序员负责例如填充缓冲区,然后发信号通知另一个线程读取它。现在,如果编译器在两个线程中以不同的方式重新排序结构怎么办...
    【解决方案2】:

    几乎没有编译器处理局部性的数据布局。它仍然是一个活跃的研究领域。

    【讨论】:

    • 您对此声明有任何引用吗?
    猜你喜欢
    • 1970-01-01
    • 2022-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多