0

CUDA a マシンでの疎行列乗算に CUSP ライブラリを使用しています。私の現在のコードは

#include <cusp/coo_matrix.h>
#include <cusp/multiply.h>
#include <cusp/print.h>
#include <cusp/transpose.h>
#include<stdio.h>
#define CATAGORY_PER_SCAN 1000
#define TOTAL_CATAGORY 100000
#define MAX_SIZE 1000000
#define ELEMENTS_PER_CATAGORY 10000 
#define ELEMENTS_PER_TEST_CATAGORY 1000
#define INPUT_VECTOR 1000
#define TOTAL_ELEMENTS ELEMENTS_PER_CATAGORY * CATAGORY_PER_SCAN
#define TOTAL_TEST_ELEMENTS ELEMENTS_PER_TEST_CATAGORY * INPUT_VECTOR
int main(void)
{
    cudaEvent_t start, stop;
    cudaEventCreate(&start);
    cudaEventCreate(&stop);
    cudaEventRecord(start, 0);
    cusp::coo_matrix<long long int, double, cusp::host_memory> A(CATAGORY_PER_SCAN,MAX_SIZE,TOTAL_ELEMENTS);
    cusp::coo_matrix<long long int, double, cusp::host_memory> B(MAX_SIZE,INPUT_VECTOR,TOTAL_TEST_ELEMENTS);

    for(int i=0; i< ELEMENTS_PER_TEST_CATAGORY;i++){    
        for(int j = 0;j< INPUT_VECTOR ; j++){
            int index = i * INPUT_VECTOR + j ;
            B.row_indices[index] = i; B.column_indices[ index ] = j; B.values[index ] = i;
        }    
    }
    for(int i = 0;i < CATAGORY_PER_SCAN;  i++){
        for(int j=0; j< ELEMENTS_PER_CATAGORY;j++){     
            int index = i * ELEMENTS_PER_CATAGORY + j ;
            A.row_indices[index] = i; A.column_indices[ index ] = j; A.values[index ] = i;
        }    
    }
    /*cusp::print(A);
    cusp::print(B); */
    //test vector
    cusp::coo_matrix<long int, double, cusp::device_memory> A_d = A;
    cusp::coo_matrix<long int, double, cusp::device_memory> B_d = B;

        // allocate output vector
    cusp::coo_matrix<int, double, cusp::device_memory>  y_d(CATAGORY_PER_SCAN, INPUT_VECTOR ,CATAGORY_PER_SCAN * INPUT_VECTOR);
    cusp::multiply(A_d, B_d, y_d);
    cusp::coo_matrix<int, double, cusp::host_memory> y=y_d;
    cudaEventRecord(stop, 0);
    cudaEventSynchronize(stop);
    float elapsedTime;
    cudaEventElapsedTime(&elapsedTime, start, stop); // that's our time!
    printf("time elaplsed %f ms\n",elapsedTime);
    return 0;
}

cusp::multiply 関数は 1 つの GPU のみを使用します (私の理解では)。

  1. setDevice() を使用して、両方の GPU (GPU ごとに 1 つの cusp::multiply) で同じプログラムを実行するにはどうすればよいですか。
  2. 合計時間を正確に測定します。
  3. 自分で malloc を使用できるため、このライブラリでゼロコピー固定メモリを使用するにはどうすればよいですか。
4

1 に答える 1

1

1 setDevice() を使用して両方の GPU で同じプログラムを実行するにはどうすればよいですか

「2 つの GPU を使用して1 つの操作を実行するにはどうすればよいか」ということであればcusp::multiply、答えは「できない」です。


編集:

異なる GPU で 2 つの別個の CUSP 疎行列 - 行列製品を実行する場合は、単純に操作をループでラップしcudaSetDevice、転送と呼び出しの前に呼び出すことができcusp::multiplyます。おそらくそうする必要はありませんが、そうすることで速度が向上します。cusp::multiplyメモリ転送と操作の両方が呼び出しをブロックしているため、ホスト CPU はそれらが完了するまでストールするというのは正しいと思います。このため、異なる GPU の呼び出しが重複することはなく、単一の GPU で同じ操作を 2 回実行するよりも高速化されません。マルチスレッド アプリケーションを使用し、複数のコアを備えたホスト CPU を使用する場合は、おそらくそれらを並列で実行できますが、期待するほど単純なホスト コードにはなりません。

2 トータルタイムを正確に計測する

現在のcuda_eventアプローチは、単一のカーネルの実行時間を測定する最も正確な方法です。仮想的なマルチ GPU スキームがある場合、各 GPU コンテキストからのイベントの合計がカーネルの合計実行時間になります。合計時間とは、操作を完了するための「ウォールクロック」時間を意味する場合、コードの multigpu セグメント全体でホスト タイマーを使用する必要があります。CUDAの最新バージョンでは、状況によっては異なるコンテキストからのストリーム内のイベント間で同期できる可能性があることをぼんやりと思い出します。そのため、CUDAイベントベースのタイマーはそのようなシナリオでも使用できる可能性があります。

3 自分で malloc を使用できるため、このライブラリでゼロコピー固定メモリを使用するにはどうすればよいですか。

私の知る限り、それは不可能です。CUSP が使用する基になるスラスト ライブラリは、ゼロ コピー メモリを使用するコンテナーをサポートできますが、CUSP は、ゼロ コピー メモリに CUSP スパース マトリックスを割り当てるために使用できるようにするために、標準のマトリックス コンストラクターで必要なメカニズムを公開しません。

于 2012-09-19T15:44:18.293 に答える