我想知道JDK什么时候会自动矢量化。我有以下一组问题(尽管我在谷歌上搜索,阅读,实验等)。下面给出一个简单的循环:
for(int i=0; size = size(); i < size; i++) {
a[i] = b[i] * c[i];
method1();
// someObject.method2();
// someHashMap.put(b[i], c[i]);
}
发布于 2018-09-04 07:30:54
要回答您的问题(1),原则上,如果Java编译器分析了method1()
并确定它没有任何影响自动向量化的副作用,那么它可以在存在非内联method1()
调用的情况下进行优化。具体地说,编译器可以证明该方法是"const“的(没有副作用,也不会从全局内存中读取),这通常会在调用点实现许多优化,而不需要内联。它还可能证明更受限制的属性,例如不读取或写入特定类型的数组,这也足以允许在这种情况下进行自动向量化。
然而,在实践中,我不知道目前有任何Java编译器可以完成这种优化。如果相信this answer的话,在热点中:“非内联方法调用对于JIT编译器来说通常是不透明的。”大多数Java编译器都以这样或那样的方式基于Hotspot,所以我不期望有一个成熟的Java编译器可以在Hotspot无法做到这一点的情况下做到这一点。
这个答案还涵盖了为什么这样的过程间分析(IPA)可能既困难又不是特别有用的一些原因。特别是,可以证明非平凡事情的方法通常足够小,以至于它们无论如何都是内联的。我不确定我是否完全同意:有人可能会争辩说,Java之所以积极地内联,部分原因是它不支持IPA,所以强大的IPA可能会提供减少内联的能力,从而减少运行时代码占用空间和JIT时间。
您在(2)或(3)中询问的其他方法变体不会改变任何东西:编译器仍然需要IPA才能将其向量化,而据我所知Java编译器没有IPA。
(4)和(5)似乎应该作为完全不同的问题来问。
关于(6)我不认为它会改变,但是对于OpenJDK热点邮件列表来说,这将是一个很好的问题:我认为你会得到一个很好的答案。
最后,值得注意的是,即使在没有IPA和对method1()
一无所知的情况下,如果编译器能够证明a
、b
和c
中的任何一个都没有转义,它也可以优化它们的数学运算。一般来说,这似乎没有什么用处:这意味着所有这些变量都会被分配到这个函数中(或者某个内联到这个函数中的函数),而我可以想象,在大多数实际场景中,至少有一个变量是由调用者传入的。
https://stackoverflow.com/questions/52150686
复制相似问题