当我使用spark mllib多层感知器模型预测向量时,我发现同一向量有时在多线程中会产生不同的结果。我阅读了源代码,发现它基于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();
    }


}

09-10 12:51
查看更多