java - BLAS.dgemm方法多线程计算误差

标签 java multithreading apache-spark apache-spark-mllib openblas

当我使用spark mllib多层感知器模型来预测 vector 时,我发现同一 vector 在多线程中有时会给出不同的结果。我阅读了源代码,发现它是基于BLAS lib的。我为BLAS在多线程中编写了一些测试代码。

我使用 BLAS dgemm utils 来计算矩阵,使用多线程时相同的矩阵数据会给出不同的结果。

我的测试代码可以在github上找到。在测试代​​码中,我人工做了一些测试数据。要使用 Windows 10 进行测试,请在 java 类路径中添加 blas dll 文件。

当我只使用一个线程来运行时:

blas.dgemm(transa, transb, m, n, k,alpha, a, _a_offset, lda, b, _b_offset, ldb,beta, c, _c_offset, ldc)

重复运行结果是一样的。但使用5个或更多线程来运行相同的数据, blas.dgemm 给出了不同的结果。这很令人困惑,为什么 blas.dgemm 中的相同数据会给出不同的结果?

使用 Windows 10,将 netlib-native_system-win-x86_64.dll 添加到 java 类路径。

最佳答案

可能存在并发问题。数组 c(堆中的同一对象)正在被所有线程同步更改。如果 a 和 b 数组在 dgemm 函数内只读。则无需克隆它们

 @Override
 public void run() {
       double[] aa=a.clone();
       double[] bb=b.clone();
       double[] cc=c.clone();
     try {

        BLAS  blas =  BLAS.getInstance();
        blas.dgemm(transa, transb, m, n, k,
                alpha, aa, _a_offset, lda, bb, _b_offset, ldb,
                beta, cc, _c_offset, ldc);

        System.out.println("c.rows:"+ m + "   c.cols:"+n
                + "   c.data:"+ Arrays.toString(cc)
                + "   c._c_offset:"+_c_offset
                + "   c.ldc:"+ldc);

    } catch (Exception e) {
        e.printStackTrace();
    }


}

关于java - BLAS.dgemm方法多线程计算误差,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47526201/

相关文章:

java - 是否有在数字屏幕上绘制 2d 对象的通用方法

java - 如何在多线程环境中生成PreparedStatement?

java - 线程类的start()方法在实现线程类时如何调用子类的run()方法

c - 在调用 pthread_join 之前到达 pthread_exit()

apache-spark - 将功能应用于Spark DataFrame的每一行

java - Spark : configuration file 'metrics.properties'

java - 获取XML中内部节点的属性

java - 升级和比较

java - 在 linux 中用 java 打印

apache-spark - 如何使用 pyspark 和自定义 python 函数处理 eventhub 流