【问题标题】:My java array code is behaving funny我的 java 数组代码的行为很有趣
【发布时间】:2014-07-23 01:52:23
【问题描述】:

我正在研究一种算法,并且一直在成功优化它,直到遇到这个奇怪的问题:

数组 C 作为参数传递给方法。

       int lim = C.length; 
      double A[]=new double[lim];
      double B[]=new double[lim];
      for (int I = offset; I < lim; I++) {
      A[ (int) B[C[I]] ] = C[I];
      }

ABdouble 数组,C 是整数数组。它们的大小都相同。
当我使用System.nanoTime() 发现时间差异时,我注意到这段代码的运行速度比它应该运行的要慢得多。

通过故障排除,我发现如果我仅将 C[I] 替换为 I 或使用嵌入代码中的值初始化的常量或任何变量,它的运行速度比它的值来自以下来源时快很多倍代码中没有预定义。

作为最后的测试,我用一个随机整数替换了C[I],得到了同样的慢速。怎么了? JVM 是否针对预定义变量优化代码?我可以合理地解决这个问题,而无需在代码中定义我的数组内容(我确信这会解决这个问题)吗?

如果我能解决这个问题,优化将产生一个新的排序算法,该算法的运行速度将比 Java 7 的 QuickSort 算法 实现快得多。对于 n

目前,我已经记录了它(在我的机器上)在 3.8-3.9 秒内对 800 万个数字(双精度类型)进行排序,而 Java 的 QuickSort implementation(Arrays.sort()) 在同一台机器上大约需要 1.53 秒。我已经在 2 个 for 循环中跟踪到这行代码的 2 次发生率,我需要帮助。

【问题讨论】:

  • 你为什么要转换成 int 已经是整数的东西?
  • 应该是A[(int)B[C[i]] ] = C[i]
  • 如何使用数组 B 中的双精度值来索引数组 A?
  • @gbenroscience 我正在投入时间学习 Java 8 中的 Lambda。我在小样本中使用了 sort 和 sort 与可比性,Lambda 让您有机会在并行模式下执行您想做的事情也是。我通过这个只是为了给你一些想法希望它有帮助
  • 感谢@Kick!我会考虑你的建议

标签: java algorithm sorting optimization compiler-optimization


【解决方案1】:

我怀疑速度变慢是由内存局部性问题引起的。

当您拥有非常大的数组时,它们将跨越多个(虚拟内存)页面。因此,如果您尝试以非顺序方式访问数组元素,您最终可能会以一种否定硬件用来使内存访问看起来更快的“智能”的效果的方式访问内存:

  • 如果您访问许多不同的位置,它们就不再适合缓存。这会导致缓存未命中,并且 CPU 必须从物理内存中获取,这会减慢速度。

  • 访问的非顺序性质意味着宽内存提取无助于提高性能。

  • 当位置分散在大量页面上时,您可能会在 TLB(翻译后备缓冲区)硬件中丢失...缓存 vm 页面条目。 TLB 未命中通常会导致 更多 次内存访问以从内存中读取页表条目。


很难说这是否真的是导致您的算法变慢的原因。 (虽然我认为你的实验结果支持这个命题……)

如果这是根本问题,那么您无能为力。它是现代计算机工作方式所固有的。如果您的算法需要对足够大的数组进行“随机”访问,则性能将受到物理内存速度的限制。

【讨论】:

  • 3 个大小为 100 万的数组会导致您描述的减速吗?我想这也取决于我机器的硬件能力?
  • 无论如何这都不是问题,因为对于大型数组(100 万及以上),当我用循环变量 i 或其他一些常量变量替换数组条目时,速度会大大提高.我怀疑一些编译器问题
  • 用循环变量替换数组条目改变内存访问的模式以增加局部性。这就是为什么我说你的实验支持这个命题。增加内存访问模式的局部性可以使您的代码运行得更快!
  • @gbenroscience - 数组越大,效果越明显。 (对于足够小的数组,这些位置都将适合内存缓存和 TLB,并且不会有很多“未命中”。)
  • 视情况而定。如果您只是将 2 个数组组合成一个大小为两倍的数组,那么它不太可能有帮助。问题是内存操作序列的局部性特征。不管是一个数组还是两个数组。
猜你喜欢
  • 1970-01-01
  • 2016-05-17
  • 2012-11-26
  • 2017-10-04
  • 1970-01-01
  • 2013-05-13
  • 1970-01-01
  • 1970-01-01
  • 2020-10-23
相关资源
最近更新 更多