2

ベクトルのベクトルがありvector<vector<double>> dataます。CUDAにはベクトルがないため、その「2Dマトリックス」に含まれる情報のみをコピーしたい。したがって、私が最初に使用したアプローチは

vector<vector<double>> *values;
vector<vector<double>>::iterator it;
double *d_values;
double *dst;

checkCudaErr(
    cudaMalloc((void**)&d_values, sizeof(double)*M*N)
);

dst = d_values;
for (it = values->begin(); it != values->end(); ++it){
    double *src = &((*it)[0]);
    size_t s = it->size();
    checkCudaErr(
        cudaMemcpy(dst, src, sizeof(double)*s, cudaMemcpyHostToDevice)
        );
    dst += s;
}

NVVP でプロファイリングした後、cudaMempcpy のスループットが非常に低くなりました。各 cudaMemcpy 呼び出しで非常に少量のバイトを送信しているため、これはロジックだと思います。そこで、これを改善するためにコードを少し変更することにしたので、2 番目のアプローチは

double *h_values = new double[M*N];

dst = h_values;
for (it = values->begin(); it != values->end(); ++it){
    double *src = &((*it)[0]);
    size_t s = it->size();
    memcpy(dst, src, sizeof(double)*s);
    dst += s;
}

checkCudaErr(
    cudaMemcpy(d_values, h_values, sizeof(double)*M*N, cudaMemcpyHostToDevice)
);

プロファイリング後の結果は、まだ memcpy スループットが低いです。それで、私の質問は、ホストからデバイスへのコピーをどのように改善できますか?

Quadro K4000 を使用しています。最初のケースでは 25 MB/秒、2 番目のケースでは約 2 GB/秒です。M = 5 および N = 2000000 です。M の値は一般的な値であると言わざるを得ませんが、50 になることもあります。

4

1 に答える 1

4

スループットが遅い理由は、double 行列を new で割り当てることが原因である可能性があります。このメモリはページ ロックされていません。システム関数 (使用するシステムがわからない) またはこの機能を提供する cuda 関数のいずれかを使用できます。だろうcudaMallocHost

あなたを削除してあなたを設定するだけです=new double[M*N](そしてもちろん削除せずに(で)解放してください)。h_valuescudaMallocHost(&h_values, sizeof(double)*M*N)cudaFreeHost

ところで。理論上の最高速度は 8 GB/秒 (PCI 2.0 x 16 レーン) ですが、実際にはそれ以下 (約 6 GB/秒) にとどまります。

于 2013-07-17T08:16:42.653 に答える