【CUDA】二、内存分配函数

       除了前面提到的内存分配函数cudaMalloc之外,这里再简单的介绍几个常用的内存分配函数:cudaMallocPitch、cudaMalloc3D等。


1、cudaMallocPitch

cudaError_t  cudaMallocPitch(void **devPtr, size_t *pitch, size_t width, size_t height);
        该函数用来分配指定大小的线性内存,宽度至少为width,高度为height,在分配2D数组的时候建议使用该函数,而不用前面提到的 cudaMallocPitch 函数,因为该函数在分配内存时会适当的填充一些字节来保证对其要求,从而在按行访问时,或者在二维数组和设备存储器的其他区域间复制是,保证了最佳的性能!(通过调用cudaMemcpy2D等类似函数)。那么实际的分配的内存大小为:sizeof(T)*pitch * height,则访问2D数组中任意一个元素[Row,Column]的计算公式如下:
T* pElement = (T*)((char*)BaseAddress + Row * pitch) + Column;
        第一个参数,void**类型,devPtr:用来接受被分配内存的其实地址
        第二个参数,size_t*类型,pitch:用来接受实际行间距,即被填充后的实际宽度(单位字节),大于等于第三个参数width
        第三个参数,size_t类型,width:请求分配内存的宽度(单位字节),如2D数组的列数
        第四个参数,size_t类型,height:请求分配内存的高度(单位字节),如2D数组的行数

2、cudaMalloc3D

cudaError_t cudaMalloc3D(struct cudaPitchedPtr* pitchedDevPtr, struct cudaExtent extent);
        该函数用来申请设备上的1D、2D、3D内存对象,同cudaMallocPitch函数一样,为了最佳的性能,会填充一些字节。
        第一个参数,cudaPitchPtr*类型,pitchedDevPtr:作为传出参数,用于记录分配得到的设备内存信息,具体结构如下:
struct  cudaPitchedPtr
	{
		void   *ptr;      //指向分配得到的设备内存地址
		size_t  pitch;    //实际被分配的宽度,单位字节
		size_t  xsize;    //逻辑宽度,记录有效的宽度,单位字节
		size_t  ysize;    //逻辑高度,记录有效的高度,单位高度
	};
        第二个参数,cudaExtent类型,extent:作为传入参数,传入所请求申请的内存信息,包括width、height、depth;具体结构如下:
struct cudaExtent
	{
		size_t width;     //请求的宽度,单位字节
		size_t height;    //请求的高度,单位字节
		size_t depth;     //请求的深度,单位字节
	};

3、相关代码

<pre name="code" class="cpp">#include <iostream>
#include <cuda_runtime.h>

using namespace std;


int main()
{
	float * pDeviceData = nullptr;
	int width = 10 * sizeof(float);
	int height = 10 * sizeof(float);
	size_t pitch;

	cudaError err = cudaSuccess;

	//1 use cudaMallocPitch function
	err = cudaMallocPitch(&pDeviceData, &pitch, width, height);		//注意这里的width和height的单位为字节数
	if (err != cudaSuccess)
	{
		cout << "call cudaMallocPitch fail!!!" << endl;
		exit(1);
	}
	cout << "width: " << width << endl;
	cout << "height: " << height << endl;
	cout << "pitch: " << pitch << endl;


	//2 use cudaMalloc3D
	cudaPitchedPtr pitchPtr;
	cudaExtent extent;
	extent.width = 10 * sizeof(float);
	extent.height = 22 * sizeof(float);
	extent.depth = 33 * sizeof(float);

	err = cudaMalloc3D(&pitchPtr, extent);
	if (err != cudaSuccess)
	{
		cout << "call cudaMalloc3D fail!!!" << endl;
		exit(1);
	}
	cout << "\n\n";
	cout << "width: " << extent.width << endl;			//输出申请内存的初始值
	cout << "height: " << extent.height << endl;
	cout << "depth: " << extent.depth << endl;

	cout << endl;
	cout << "pitch: " << pitchPtr.pitch << endl;		//输出实际的宽度值
	cout << "xsize: " << pitchPtr.xsize << endl;		//有效宽度--等于extent.width
	cout << "ysize: " << pitchPtr.ysize << endl;		//有效高度--等于extent.height

	cudaFree(pDeviceData);
	cudaFree(pitchPtr.ptr);
	cin.get();
	return 0;
}


 

4、运行结果

5、其他相关设备内存操作函数

        注意,以上两个内存分配函数分配的都是线性内存!
        cudaMemset3D,
        cudaMalloc3DArray,
        cudaMallocArray,
        cudaFreeArray,
        cudaMallocHost(void**, size_t) 
        cudaMallocHost (C API)",
        cudaFreeHost, 
        cudaHostAlloc, 
        make_cudaPitchedPtr,         //用于创建cudaPitchedPtr对象
        make_cudaExtent                 //用于创建cudaExtent对象



  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
CUDA Fortran(也称为Fortran编程语言的CUDA扩展)是一种用于在GPU上执行并行计算的编程模型。CUDA Fortran提供了一种简单而高效的方式来开发并行GPU应用程序,尤其适用于科学计算和数值计算。 在CUDA Fortran中,设备端函数是在GPU上执行的函数。它们可以并行地在多个线程中执行,以加速计算。设备端函数CUDA Fortran编写,在运行时在GPU上运行。与传统的Fortran函数不同,设备端函数可以通过使用CUDA语言扩展来利用GPU的并行特性。 在创建设备端函数时,我们需要使用特殊的编译器指令来标识这是一个设备端函数,例如`!$acc routine`。设备端函数的参数和返回值必须在设备内存中分配,并且必须使用特殊的语法进行传递。CUDA Fortran提供了一些内置函数和指令,用于操作设备内存和执行并行计算。 设备端函数通常与主机端函数(在CPU上执行的函数)结合使用,以实现在GPU和CPU之间的数据传输和计算分工。主机端函数负责数据的输入和输出,以及将计算任务分配给GPU。设备端函数执行实际的计算任务,并将结果传递回主机端函数。 总而言之,设备端函数是在GPU上执行的CUDA Fortran函数。它们可以实现并行计算,并与主机端函数相结合,以加速计算任务。CUDA Fortran为科学计算和数值计算提供了一种强大的编程模型,使开发者能够更好地利用GPU的并行计算能力。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值