gpt4 book ai didi

c++ - Mex Cuda 动态分配/慢速 mex 代码

转载 作者:太空狗 更新时间:2023-10-29 21:20:20 25 4
gpt4 key购买 nike

我有返回 C++ 主机端数组的 cuda/C++ 代码。我想在 MATLAB 中操作这些数组,所以我用 mex 格式重写了我的代码并用 mex 编译。

我通过将预分配的数组从 MATLAB 传递到 mex 脚本来让它工作,但这会疯狂地减慢速度。 (54 秒 vs 14 秒没有 mex)

这是我的代码的简化、无输入 1 输出版本的缓慢解决方案:

#include "mex.h"
#include "gpu/mxGPUArray.h"
#include "matrix.h"
#include <stdio.h>
#include <stdlib.h>
#include "cuda.h"
#include "curand.h"
#include <cuda_runtime.h>
#include "math.h"
#include <curand_kernel.h>
#include <time.h>
#include <algorithm>
#include <iostream>

#define iterations 159744
#define transMatrixSize 2592 // Just for clarity. Do not change. No need to adjust this value for this simulation.
#define reps 1024 // Is equal to blocksize. Do not change without proper source code adjustments.
#define integralStep 13125 // Number of time steps to be averaged at the tail of the Force-Time curves to get Steady State Force

__global__ void kern(float *masterForces, ...)
{

int globalIdx = ((blockIdx.x + (blockIdx.y * gridDim.x)) * (blockDim.x * blockDim.y)) + (threadIdx.x + (threadIdx.y * blockDim.x));
...

...
{
...
{
masterForces[i] = buffer[0]/24576.0;
}

}
}
...
}



}


void mexFunction(int nlhs, mxArray *plhs[],
int nrhs, mxArray const *prhs[])
{
...

plhs[0] = mxCreateNumericMatrix(iterations,1,mxSINGLE_CLASS,mxREAL);
float *h_F0 = (float*) mxGetData(plhs[0]);


//Device input vectors
float *d_F0;

..
// Allocate memory for each vector on GPU
cudaMalloc((void**)&d_F0, iterations * sizeof(float));
...




//////////////////////////////////////////////LAUNCH ////////////////////////////////////////////////////////////////////////////////////

kern<<<1, 1024>>>( d_F0);



//////////////////////////////////////////////RETRIEVE DATA ////////////////////////////////////////////////////////////////////////////////////


cudaMemcpyAsync( h_F0 , d_F0 , iterations * sizeof(float), cudaMemcpyDeviceToHost);



///////////////////Free Memory///////////////////


cudaDeviceReset();
////////////////////////////////////////////////////

}

为什么这么慢?

编辑:Mex 正在使用旧架构 (SM_13) 而非 SM_35 进行编译。现在是时候了。 (mex 16 秒,仅 c++/cuda 14 秒)

最佳答案

如果您的 CUDA 代码的输出是纯旧数据 (POD) 主机端(相对于设备端)数组,则无需使用 mxGPUArray,例如您的 Forces1new 创建的 float 数组。您引用的 MathWorks 示例可能演示了 MATLAB 的 gpuArray 和内置 CUDA 功能的使用,而不是如何在 MEX 函数中将数据传入和传出常规 CUDA 函数。

如果您可以在 CUDA 函数之外和之前(例如在 mexFunction),那么解决方案就是将 new 更改为 mxCreate* 函数之一(即 mxCreateNumericArraymxCreateDoubleMatrixmxCreateNumericMatrix 等),然后将数据指针传递给您的 CUDA 函数:

plhs[0] = mxCreateNumericMatrix(iterations,1,mxSINGLE_CLASS,mxREAL);
float *h_F0 = (float*) mxGetData(plhs[0]);
// myCudaWrapper(...,h_F0 ,...) /* i.e. cudaMemcpyAsync(h_F0,d_F0,...)

您的代码唯一的变化是:

替换:

float *h_F0 = new float[(iterations)];

plhs[0] = mxCreateNumericMatrix(iterations,1,mxSINGLE_CLASS,mxREAL);
float *h_F0 = (float*) mxGetData(plhs[0]);

移除:

delete h_F0;

注意:如果您的 CUDA 代码拥有输出主机端数组,则您必须复制数据mxArray 中。这是因为除非您使用 mx API 分配 mexFunction 输出,否则您分配的任何数据缓冲区(例如使用 mxSetData)将不会被处理MATLAB 内存管理器,您将遇到段错误或充其量是内存泄漏。

关于c++ - Mex Cuda 动态分配/慢速 mex 代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24876229/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com