【cuda】二、基础知识: 内存管理 同步

这篇具有很好参考价值的文章主要介绍了【cuda】二、基础知识: 内存管理 同步。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

在CUDA中,使用**cudaMalloc()来分配设备内存,使用cudaFree()**来释放设备内存。

cudaMallocManaged 统一内存管理

**统一虚拟寻址(Unified Memory):使用cudaMallocManaged()**来分配可以在CPU和GPU之间共享的内存。无需关心数据在主机或设备上。

cudaMallocManaged是一个CUDA运行时应用程序接口(API)函数,用于分配统一内存(unified memory)。统一内存是CUDA的一种内存管理模型,它提供了一个单一的、在主机和设备间共享的内存空间

这个函数的原型如下:

__host__ cudaError_t cudaMallocManaged ( void** devPtr, size_t size, unsigned int  flags = cudaMemAttachGlobal );
  • devPtr 是一个指针,指向分配的内存的地址。
  • size 是请求分配的内存的字节数。
  • flags 是一个可选的参数,用于指示内存的附着行为。默认值是 cudaMemAttachGlobal,意味着这块内存在所有的CUDA流中都是可见的。

cudaMallocManaged函数的工作原理是基于按需页面迁移"(on-demand page migration)的机制。当GPU要访问一块统一内存时,如果这块内存当前并不在GPU的物理内存中,就会触发一个页面迁移,将数据从CPU内存迁移到GPU内存。同样,当CPU要访问一块统一内存时,如果这块内存当前在GPU内存中,就会触发一个页面迁移,将数据从GPU内存迁移到CPU内存。

页面迁移可能引发的性能开销。如果主机和设备频繁地对同一块内存进行访问,可能会导致"抖动"现象,即数据不断地在主机和设备间迁移,这会大大降低程序的性能。

cudaDeviceSynchronize() &cudaStreamSynchronize()等待操作完成

cudaDeviceSynchronize()是一个CUDA运行时应用程序接口(API)函数,用于阻塞主机代码的执行,直到设备上所有先前的任务都完成为止。这包括内核执行以及设备与主机之间的内存传输。

这个函数在调试和性能测量中非常有用,因为它可以确保所有设备上的任务在继续执行主机代码之前都已完成。例如,如果你想测量GPU内核的执行时间,你需要在内核启动和停止之间插入cudaDeviceSynchronize()来确保内核完成执行。

然而,cudaDeviceSynchronize()应谨慎使用,因为它会阻塞主机代码的执行,这可能会导致性能下降。在生产代码中,通常优先使用非阻塞同步函数(如cudaStreamSynchronize()),这样可以在设备执行任务时让主机执行其他任务。

cudaMemPrefetchAsync 预迁移数据

cudaMemPrefetchAsync用于管理和优化数据在主机和设备之间的迁移,此函数可以预先迁移数据。

cudaMemPrefetchAsync的工作原理主要是基于CUDA内存管理系统和硬件的协作。当调用此函数时,CUDA运行时系统会在后台发起一个数据迁移操作,将数据从源设备迁移到目标设备。
如果目标设备是GPU,系统会将数据从主机内存复制到GPU内存。这个操作通常在CPU调用cudaMemPrefetchAsync之后立即开始,但实际的开始时间取决于系统的调度策略和设备的负载情况。一旦数据迁移到GPU,GPU上的CUDA内核就可以直接访问这些数据,而无需等待从主机内存的迁移。这可以大大减少内存访问的延迟,提高程序的性能。
如果目标设备是CPU,系统会将数据从GPU内存复制回主机内存。这个操作在GPU完成其上的所有先前操作之后才开始,以保证数据的一致性。一旦数据迁回主机,CPU就可以直接访问这些数据,无需等待从GPU内存的迁移。这对于需要在CPU上进一步处理的数据非常有用。
cudaMemPrefetchAsync函数还可以接受一个CUDA流作为参数,用于控制数据迁移的执行顺序。在同一个流中,操作按照它们被提交的顺序执行。这意味着,如果在同一个流中先后调用cudaMemPrefetchAsync和一个CUDA内核,那么CUDA运行时系统会确保数据迁移完成后才开始执行内核。这种机制提供了一种在GPU和CPU之间精细控制数据流的方式。

函数的原型如下:

cudaError_t cudaMemPrefetchAsync(const void* devPtr, size_t count, int  dstDevice, cudaStream_t stream = 0);

其中,

  • devPtr 是一个指向需要迁移的数据的指针。
  • count 是需要迁移的数据的字节数。
  • dstDevice 是目标设备。例如,可以设置为特定的GPU设备ID,或者设置为cudaCpuDeviceId表示CPU。
  • stream 是一个可选参数,表示CUDA流,用于异步操作。

通过使用cudaMemPrefetchAsync,可以控制何时以及如何将数据迁移至GPU或CPU,从而优化程序性能,减少内存访问的延迟。

CUDA Stream

在CUDA编程模型中,Stream可以被看作是设备上执行的一系列命令的队列。这些命令可以包括内核的执行、内存传输等。在同一个stream中,这些命令是按照它们入队列的顺序来执行的。而不同的stream之间则可以并发执行,这使得我们可以通过合理地使用多个stream来提高程序的并行度,从而提高程序的执行效率。

在CUDA中,我们可以通过cudaStreamCreate函数来创建一个新的stream。以下是一个简单的例子:

cudaStream_t stream;
cudaStreamCreate(&stream);

首先定义了一个cudaStream_t类型的变量stream,然后调用了cudaStreamCreate函数来创建一个新的stream,这个新创建的stream的句柄被存储在stream变量中。

我们可以在调用内核或者内存传输函数时指定stream参数,例如:

myKernel<<<gridDim, blockDim, 0, stream>>>(...);
cudaMemcpyAsync(dst, src, count, cudaMemcpyHostToDevice, stream);

在这个例子中,我们在调用myKernel内核和cudaMemcpyAsync函数时分别指定了stream参数,这意味着这两个操作将会在我们创建的stream中被执行。

在使用完stream后,我们需要调用cudaStreamDestroy函数来释放stream占用的资源,例如:文章来源地址https://www.toymoban.com/news/detail-800088.html

cudaStreamDestroy(stream);// 销毁流

到了这里,关于【cuda】二、基础知识: 内存管理 同步的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 数电与Verilog基础知识之同步和异步、同步复位与异步复位

    同步和异步是两种不同的处理方式,它们的区别主要在于是否需要等待结果。同步是指一个任务在执行过程中,必须等待上一个任务完成后才能继续执行下一个任务;异步是指一个任务在执行过程中,不需要等待上一个任务完成,可以同时执行多个任务。同步和异步的优缺点

    2024年02月14日
    浏览(38)
  • C语言基础知识:内存分配

    目录 内存分配原理 内存分配方法 静态内存分配 动态内存分配 MALLOC() CALLOC()/

    2024年02月07日
    浏览(30)
  • 操作系统基础知识介绍之内存层次结构(一)

    传统上,内存层次结构的设计者专注于优化平均内存访问时间,这由缓存访问时间、未命中率和未命中惩罚决定。 然而,最近,功率已成为主要考虑因素。 在高端微处理器中,可能有 60 MiB 或更多的片上高速缓存,并且大型二级或三级高速缓存将消耗大量功率。 这个问题在

    2024年02月04日
    浏览(33)
  • JVM基础知识(内存区域划分,类加载,GC垃圾回收)

    目录 内存区域划分 JVM中的栈 JVM中的堆 程序计数器 方法区(元数据区) 给一段代码,某个变量在哪个区域上? 类加载 类加载时机 双亲委派模型 GC 垃圾回收机制 GC 实际工作过程 1.找到垃圾/判定垃圾 1.可达性分析(Java中的做法) 2.引用计数 2.清理垃圾 1.标记清除 2.复制算法 3.标记整

    2024年02月07日
    浏览(48)
  • 并发编程的基础知识

    并发编程的优缺点 充分利用多核CPU的计算能力:通过并发编程的形式可以将多核CPU的计算能力发挥到极致,性能得到提升 方便进行业务拆分,提升系统并发能力和性能:在特殊的业务场景下,先天的就适合于并发编程。现在的系统动不动就要求百万级甚至千万级的并发量,

    2024年02月06日
    浏览(24)
  • 网络基础知识&socket编程

    Linux 系统是依靠互联网平台迅速发展起来的,所以它具有强大的网络功能支持,也是Linux 系统的一大特点。互联网对人类社会产生了巨大影响,它几乎改变了人们生活的方方面面,可见互联网对人类社会的重要性! 本章我们便来学习一些网络基础知识,如果感兴趣的读者可以

    2024年02月10日
    浏览(33)
  • 并发编程基础知识篇--并发编程的优点&缺点

    目录 并发编程的优点缺点 为什么要使用并发编程(优点): 并发编程的缺点: 频繁的上下文切换 线程安全 易混淆的概念 阻塞与非阻塞 阻塞模型 非阻塞模型 同步与异步 同步调用 异步调用 临界区 并发与并行 上下文切换 并发编程是指在程序中同时执行多个独立的任务或操

    2024年02月11日
    浏览(32)
  • 复习并发编程的基础知识(一)

    目录 进程和线程 并发和并行  如何创建一个线程? 1,继承Thread类  2,实现Runnable接口          3. Callable接口 线程Thread类的一些重要方法  守护线程: 时间长了,并发编程的基础知识总忘,来记录一下: 进程和线程 进程:资源分配的最小单元,什么是资源?CPU,内存,网

    2024年02月08日
    浏览(36)
  • FPGA基础知识-编程语言接口

    目录 学习目标: 学习内容: 1.PLI的使用 2.PLI任务的连接和调用 3.内部数据的获取 4.PLI库子程序 学习时间: 学习产出: 解释在Verilog仿真中如何使用PLI子程序。 描述PLI的用途。 定义用户自定义系统任务和函数以及用户自定义C子程序。 理解用户自定义系统任务的连接和调用。

    2024年02月11日
    浏览(25)
  • Linux网络编程 网络基础知识

    目录 1.网络的历史和协议的分成 2.网络互联促成了TCP/IP协议的产生 3.网络的体系结构 4.TCP/IP协议族体系 5.网络各层的协议解释 6.网络的封包和拆包 7.网络预备知识      Internet-\\\"冷战\\\"的产物 1957年十月和十一月,前苏联先后欧两颗”Spuinik”卫星上天 1958年美国总统艾森豪威尔向

    2024年02月10日
    浏览(29)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包