Parallel processing 使用CUDA的GPU设备和零拷贝固定内存

Parallel processing 使用CUDA的GPU设备和零拷贝固定内存,parallel-processing,cuda,sparse-matrix,matrix-multiplication,Parallel Processing,Cuda,Sparse Matrix,Matrix Multiplication,我正在CUDA机器上使用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

我正在CUDA机器上使用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;
}
#包括
#包括
#包括
#包括
#包括
#每扫描1000次定义分类
#定义总类别100000
#定义最大大小1000000
#根据类别10000定义元素
#根据测试类别1000定义元素
#定义输入向量1000
#定义每个类别的总元素*每个扫描的类别
#定义每个测试类别的总测试元素*输入向量
内部主(空)
{
cudaEvent\u t启动、停止;
cudaEventCreate(&start);
cudaEventCreate(&stop);
cudaEventRecord(开始,0);
cusp::coo_矩阵A(每_扫描的分类、最大尺寸、总元素);
cusp::coo_矩阵B(最大_大小、输入_向量、总_测试元素);
对于(inti=0;i
cusp::multiply函数仅使用1个GPU(据我所知)

  • 如何使用setDevice()在两个GPU上运行相同的程序(每个GPU一个cusp::乘法)
  • 准确测量总时间
  • 我如何使用这个库的零拷贝固定内存,就像我自己可以使用malloc一样
  • 1如何使用setDevice()在两个GPU上运行相同的程序

    如果您的意思是“如何使用两个GPU执行单个
    cusp::multiply
    操作”,那么答案是您不能


    编辑:

    对于希望在不同GPU上运行两个单独的CUSP稀疏矩阵乘积的情况,可以简单地将操作包装在一个循环中,并在传输和调用
    CUSP::multiply
    之前调用
    cudaSetDevice
    。然而,这样做可能不会加快速度。我想我说的是正确的,内存传输和cusp::multiply操作都会阻塞调用,因此主机CPU将暂停,直到它们完成。因此,对不同GPU的调用不能重叠,并且在单个GPU上执行相同操作两次不会有速度提升。如果您愿意使用多线程应用程序,并且有一个具有多个内核的主机CPU,那么您可能仍然可以并行运行它们,但它不会像您希望的那样简单

    2准确测量总时间

    您现在使用的
    cuda_事件
    方法是测量单个内核执行时间的最准确方法。如果您有一个超理想的多gpu方案,那么来自每个gpu上下文的事件之和就是内核的总执行时间。如果“总时间”指的是完成操作的“wallclock”时间,那么您需要在代码的整个multigpu段上使用主机计时器。我隐约记得,在最新版本的CUDA中,在某些情况下可能会在来自不同上下文的流中的事件之间进行同步,因此基于CUDA事件的计时器在这种情况下可能仍然可用

    3我如何在这个库中使用零拷贝固定内存,就像我自己可以使用malloc一样


    就我所知那是不可能的。CUSP使用的底层推力库可以支持使用零拷贝内存的容器,但是CUSP没有公开标准矩阵构造函数中的必要机制,以便能够在零拷贝内存中使用分配CUSP稀疏矩阵。

    我已经编辑了我的问题。基本上我的意思是1 cusp::multiply per GPU。@终端是你真正的问题,事实上,你已经完成了这段代码的多GPU版本,但你不明白为什么要花两倍于在一个GPU上运行单个调用的时间?实际上我想知道在哪里确切地使用setDevice()这样我就可以加载更多的数据,并与原始数据一起运行并行矩阵乘法。@Terminal:看看我的编辑。我非常确定您使用的所有调用都是阻塞的,因此如果您使用单个主机线程,您将无法从两个GPU获得并行速度。