1

我正在尝试计算 450 个向量之间的互相关,每个向量的大小为 20000。在 CPU 上执行此操作时,我将数据存储在 2D 矩阵中,行数 = 20000,列数 = 450。

计算的串行代码看起来像

    void computeFF_cpu( float * nSamples, float * nFeatures, float ** data, float ** corr
        #pragma omp parallel for shared(corr, data)
        for( int i=0 ; i<nFeatures ; i++ )
        {
            for( int j=0 ; j<nFeatures ; j++ )
                corr[i][j] = pearsonCorr( data[i], data[j], nSamples );
        }

int main()
{
.
.
**for( int z=0 ; z<1000 ; z++ )**
computeFF_cpu( 20000, 450, data, corr );
.
.
}

这完美地工作。现在我尝试用 GPU 解决这个问题。我已将 2D 数据矩阵转换为 GPU 内存中的行主要格式,并且我已验证复制是否正确。

这些向量以行主要格式存储为大小为 900000(即 450*20000)的矩阵。组织如下
<---f1的nSamples---><---f2的nSamples ---><---f3的nSamples--->......

我计算互相关的 cuda 代码如下

    // kernel for computation of ff
    __global__ void computeFFCorr(int nSamples, int nFeatures, float * dev_data, float * dev_ff)
    {
        int tid = blockIdx.x + blockIdx.y*gridDim.x;
        if( blockIdx.x == blockIdx.y )
        dev_ff[tid] = 1.0;
        else if( tid < nFeatures*nFeatures )
        dev_ff[tid] = pearsonCorrelationScore_gpu( dev_data+(blockIdx.x*nSamples), dev_data+(blockIdx.y*nSamples), nSamples );
    }

    main()
    {
    .
    .
        // Call kernel for computation of ff
**for( int z=0 ; z<1000 ; z++ )**
        computeFFCorr<<<dim3(nFeatures,nFeatures),1>>>(nSamples, nFeatures, dev_data, corr);
        //nSamples = 20000
        // nFeatures = 450
        // dev_data -> data matrix in row major form
        // corr -> result matrix also stored in row major
    .
    .
    }
4

1 回答 1

1

好像我已经找到了自己问题的答案。我有以下实验。我已经更改了 z 的值(即函数执行的次数)。这种方法在之前的几篇关于 cuda 标签下的 stackoverflow 的文章中被提出。

这是表——

  • Z=100 ; CPU=11s ; GPU=14s
  • Z=200 ; CPU=18s ; GPU=23s
  • Z=300 ; CPU=26s ; GPU=34s
  • Z=500 ; CPU=41s ; GPU=53s
  • Z=1000;CPU=99s ; GPU=101s
  • Z=1500;CPU=279s;GPU=150s
  • Z=2000;CPU=401s;GPU=203s

很明显,随着计算量的增加,GPU 的扩展能力比 CPU 好得多。

于 2013-02-01T13:07:00.813 回答