Java 向量化计算的最佳实践
Java best practices for vectorized computations
我正在研究在 Java 中计算昂贵向量运算的方法,例如大矩阵之间的点积或乘法。关于这个主题,这里有一些很好的话题,比如 this and this。
似乎没有可靠的方法让 JIT 编译代码使用 CPU 矢量指令(SSE2、AVX、MMX...)。此外,高性能线性代数库(ND4J、jblas 等)实际上确实会为核心例程对 BLAS/LAPACK 库进行 JNI 调用。我理解 BLAS/LAPACK 包是 事实上 本地线性代数计算的标准选择。
另一方面,其他人(JAMA,...)在没有 native
调用的情况下以纯 Java 实现算法。
我的问题是:
- 此处的最佳做法是什么?
native
调用 BLAS/LAPACK 实际上是推荐的选择吗?还有其他值得考虑的库吗?
- 与性能提升相比,JNI 调用的开销是否可以忽略不计?有没有人知道阈值在哪里(例如,输入应该多小才能使 JNI 调用比纯 Java 例程更昂贵?)
- 可移植性权衡有多大?
我希望这个问题对那些开发自己的计算例程的人以及那些只想在不同实现之间做出有根据的选择的人都有帮助。
不胜感激!
没有针对每种情况的明确最佳做法。您是 could/should 使用纯 Java 解决方案(不使用 SIMD 指令)还是(使用 SIMD 优化)通过 JNI 的本机代码取决于您的特定应用程序,特别是数组的大小以及对目标的可能限制系统.
- 可能要求您不允许在目标系统中安装特定的本机库,并且尚未安装 BLAS。在那种情况下,您只需使用 Java 库。
- 纯 Java 库对于长度远小于 100 的数组往往表现更好,并且在之后的某个时候,您可以通过 JNI 使用本机库获得更好的性能。一如既往,您的里程可能会有所不同。
已执行相关基准测试(顺序随机):
- http://ojalgo.org/performance_ejml.html
- http://lessthanoptimal.github.io/Java-Matrix-Benchmark/
- Performance of Java matrix math libraries?
这些基准可能会造成混淆,因为它们提供的信息量很大。一个库对于某些操作可能更快,而对于其他操作可能更慢。另请记住,可能有不止一种 BLAS 实现可用于您的系统。我目前在我的系统上安装了 3 个 blas、atlas 和 openblas。除了选择包装 BLAS 实现的 Java 库之外,您还必须选择底层 BLAS 实现。
This answer 有一个相当最新的列表,除了它没有提到相当新的 nd4j。请记住,jeigen 依赖于 eigen 而不是 BLAS。
我正在研究在 Java 中计算昂贵向量运算的方法,例如大矩阵之间的点积或乘法。关于这个主题,这里有一些很好的话题,比如 this and this。
似乎没有可靠的方法让 JIT 编译代码使用 CPU 矢量指令(SSE2、AVX、MMX...)。此外,高性能线性代数库(ND4J、jblas 等)实际上确实会为核心例程对 BLAS/LAPACK 库进行 JNI 调用。我理解 BLAS/LAPACK 包是 事实上 本地线性代数计算的标准选择。
另一方面,其他人(JAMA,...)在没有 native
调用的情况下以纯 Java 实现算法。
我的问题是:
- 此处的最佳做法是什么?
native
调用 BLAS/LAPACK 实际上是推荐的选择吗?还有其他值得考虑的库吗?- 与性能提升相比,JNI 调用的开销是否可以忽略不计?有没有人知道阈值在哪里(例如,输入应该多小才能使 JNI 调用比纯 Java 例程更昂贵?)
- 可移植性权衡有多大?
我希望这个问题对那些开发自己的计算例程的人以及那些只想在不同实现之间做出有根据的选择的人都有帮助。
不胜感激!
没有针对每种情况的明确最佳做法。您是 could/should 使用纯 Java 解决方案(不使用 SIMD 指令)还是(使用 SIMD 优化)通过 JNI 的本机代码取决于您的特定应用程序,特别是数组的大小以及对目标的可能限制系统.
- 可能要求您不允许在目标系统中安装特定的本机库,并且尚未安装 BLAS。在那种情况下,您只需使用 Java 库。
- 纯 Java 库对于长度远小于 100 的数组往往表现更好,并且在之后的某个时候,您可以通过 JNI 使用本机库获得更好的性能。一如既往,您的里程可能会有所不同。
已执行相关基准测试(顺序随机):
- http://ojalgo.org/performance_ejml.html
- http://lessthanoptimal.github.io/Java-Matrix-Benchmark/
- Performance of Java matrix math libraries?
这些基准可能会造成混淆,因为它们提供的信息量很大。一个库对于某些操作可能更快,而对于其他操作可能更慢。另请记住,可能有不止一种 BLAS 实现可用于您的系统。我目前在我的系统上安装了 3 个 blas、atlas 和 openblas。除了选择包装 BLAS 实现的 Java 库之外,您还必须选择底层 BLAS 实现。
This answer 有一个相当最新的列表,除了它没有提到相当新的 nd4j。请记住,jeigen 依赖于 eigen 而不是 BLAS。