Cuda: решение наименьших квадратов, плохая скорость

В последнее время я использую Cuda для написания алгоритма под названием «Погоня за ортогональным соответствием». В моем уродливом коде Cuda вся итерация занимает 60 секунд, а Eigen lib занимает всего 3 секунды ...

В моем коде Матрица A - это [640,1024], а y - [640,1], на каждом шаге я выбираю несколько векторов из A, чтобы составить новую Матрицу с именем A_temp [640, itera], iter = 1: 500. Я новый массив MaxDex_Host [] в CPU, чтобы сказать, какой столбец выбрать.

Я хочу получить x_temp [itera, 1] из A_temp * x_temp = y, используя метод наименьших квадратов, я использую cula API 'culaDeviceSgels' и API умножения матрицы на векторные кубы.

Таким образом, culaDeviceSgels будет вызывать 500 раз, и я думаю, что это будет быстрее, чем QR.Sovler от Eigen lib.

Я проверил анализ производительности Nisight, я обнаружил, что история занимает много времени. Я инициализирую кублы до итерации и уничтожаю их после получения результата. Итак, я хочу знать, что такое custreamdestory, отличается от cublasdestory?

Основная проблема - это memcpy и функция 'gemm_kernel1x1val'. Я думаю, что эта функция от 'culaDeviceSgels'

while (итера <500): я использую cublasSgemv и cublasIsamax, чтобы получить MaxDex_Host [итера], затем

        MaxDex_Host[itera]=pos;
    itera++; 
    float* A_temp_cpu=new float[M*itera]; // matrix all in col-major
    for (int j=0;j<itera;j++) // to  get A_temp [M,itera] , the MaxDex_Host[] shows the positon of which column of A to chose , 
    {
        for (int i=0;i<M;i++) //M=640 , and A is 640*1024 ,itera is add 1 each step
        {
            A_temp_cpu[j*M+i]=A[MaxDex_Host[j]*M+i];
        }
    }
          // I must allocate one more array because culaDeviceSgels will decompose the one input Array ,  and I want to use A_temp after least-square solving.
    float* A_temp_gpu;
    float* A_temp2_gpu;  
    cudaMalloc((void**)&A_temp_gpu,Size_float*M*itera);
    cudaMalloc((void**)&A_temp2_gpu,Size_float*M*itera);
    cudaMemcpy(A_temp_gpu,A_temp_cpu,Size_float*M*itera,cudaMemcpyHostToDevice);
    cudaMemcpy(A_temp2_gpu,A_temp_gpu,Size_float*M*itera,cudaMemcpyDeviceToDevice);
    culaDeviceSgels('N',M,itera,1,A_temp_gpu,M,y_Gpu_temp,M);// the x_temp I want is in y_Gpu_temp's return value ,  stored in the y_Gpu_temp[0]——y_Gpu_temp[itera-1]
     float* x_temp;
    cudaMalloc((void**)&x_temp,Size_float*itera);
    cudaMemcpy(x_temp,y_Gpu_temp,Size_float*itera,cudaMemcpyDeviceToDevice);

Управление памятью у Cuda кажется слишком сложным, есть ли другой удобный метод для решения методом наименьших квадратов?

Ответы на вопрос(1)

Ваш ответ на вопрос