优化器能否摆脱对空间局部性的不良使用?我正在维护一些由其他人编写的代码,并且他们的许多数组都是以随意的顺序声明的,并且每次调用它们时都会以不同的方式进行迭代。
由于代码的复杂性,每次循环阵列时都需要花费大量时间来尝试和重新管理。我在阅读汇编语言方面不够熟练,无法准确判断不同优化级别的不同之处,但我的问题是,
在编写程序时,局部性很重要,还是会被优化掉,这样我就不用担心了?
优化器能否摆脱对空间局部性的不良使用?我正在维护一些由其他人编写的代码,并且他们的许多数组都是以随意的顺序声明的,并且每次调用它们时都会以不同的方式进行迭代。
由于代码的复杂性,每次循环阵列时都需要花费大量时间来尝试和重新管理。我在阅读汇编语言方面不够熟练,无法准确判断不同优化级别的不同之处,但我的问题是,
在编写程序时,局部性很重要,还是会被优化掉,这样我就不用担心了?
获得正确的位置很重要,因为它可以在运行时产生两个数量级的差异(如果您有页面错误,则为 5-6 个数量级)。
除了真正的编译器通常不会自动处理这一事实(如 Joel Falcou 所说)之外,即使是假设的编译器也很难做到这一点。在很多情况下,编译器做这样的事情甚至可能是无效的,而且很难预测什么时候是,什么时候不是。
例如,您有在 CPU 上计算的顶点数据,并将其上传到图形 API,例如 OpenGL 或 DirectX。您已经同意该 API 的某个顶点数据布局。现在编译器认为以某种方式重新排列布局更有效。砰,你死定了。
编译器应该怎么知道?
假设你有几个数组和几个指针,一些指针别名其他指针,或者由于某种原因一些指向数组中间,另一些指向开头。编译器认为以不同的顺序执行某些操作会更有效,用另一个结果覆盖一个结果。
撇开数据损坏问题不谈,假设这些数组“有点大”,所以它们肯定会被动态分配而不是在堆栈上。这意味着从编译器的角度来看,它们的起始地址是“不确定的”甚至是“随机的”。编译器将如何做出决定——在编译时——不知道一半的细节?
几乎没有编译器处理局部性的数据布局。它仍然是一个活跃的研究领域。