热门标签 | HotTags
当前位置:  开发笔记 > 开发工具 > 正文

如何将CUDA固定的“零复制”内存用于内存映射文件?

如何解决《如何将CUDA固定的“零复制”内存用于内存映射文件?》经验,为你挑选了1个好方法。

在我看来,当前cupy没有提供固定的分配器来代替普通的设备内存分配器,即可以用作固定的分配器cupy.ndarray。如果这对您很重要,那么您可以考虑提出一个冒号的问题。

但是,似乎可以创建一个。这应视为实验代码。并且有一些与其使用相关的问题。

基本思想是,我们将使用cupy.cuda.set_allocator已经建议的方式,用我们自己的来替换cupy的默认设备内存分配器。我们需要提供自己的替代品,以BaseMemory用作的存储库cupy.cuda.memory.MemoryPointer。此处的主要区别在于,我们将使用固定的内存分配器而不是设备分配器。这是PMemory以下课程的要点。

需要注意的其他事项:

在使用固定的内存(分配)完成所需的操作之后,您可能应该将cupy分配器恢复为其默认值。不幸的是,与不同cupy.cuda.set_allocator,我没有找到对应的cupy.cuda.get_allocator,这使我感到不足cupy,这似乎也值得向我提出杯状问题。但是,对于本演示,我们将仅返回到None使用默认设备内存分配器之一的选择(但是不使用池分配器)。

通过提供这种最小的固定内存分配器,我们仍然建议cupy这是普通的设备内存。这意味着不能直接从宿主代码访问它(实际上,但是cupy不知道)。因此,各种操作(例如cupy.load)将创建不需要的主机分配和不需要的复制操作。我认为解决这个问题将需要的不仅是我建议的小改变。但至少对于您的测试用例,此额外开销可能是可管理的。看来您想一次从磁盘加载数据,然后将其保留在那里。对于这种类型的活动,这应该是可管理的,尤其是因为您将其分为多个部分。就像我们将看到的那样,对于25GB的主机内存来说,处理四个5GB的块实在太多了。我们将需要为四个5GB块(实际上是固定的)分配主机内存,并且还需要一个额外的5GB“开销”缓冲区的额外空间。因此25GB不足以实现这一目标。但是出于演示目的,

与cupy的默认设备内存分配器关联的普通设备内存与特定设备有关联。固定的内存不必具有这样的关联,但是BaseMemory用类似的类对我们的琐碎替换意味着我们建议cupy该“设备”内存与所有其他普通的设备内存一样,具有特定的设备关联。在您这样的单个设备设置中,这种区别是没有意义的。但是,这不适用于固定内存的强大多设备使用。为此,再次建议cupy是通过提出问题来对进行更有效的更改。

这是一个例子:

import os
import numpy as np
import cupy



class PMemory(cupy.cuda.memory.BaseMemory):
    def __init__(self, size):
        self.size = size
        self.device_id = cupy.cuda.device.get_device_id()
        self.ptr = 0
        if size > 0:
            self.ptr = cupy.cuda.runtime.hostAlloc(size, 0)
    def __del__(self):
        if self.ptr:
            cupy.cuda.runtime.freeHost(self.ptr)

def my_pinned_allocator(bsize):
    return cupy.cuda.memory.MemoryPointer(PMemory(bsize),0)

cupy.cuda.set_allocator(my_pinned_allocator)

#Create 4 .npy files, ~4GB each
for i in range(4):
    print(i)
    numpyMemmap = np.memmap( 'reg.memmap'+str(i), dtype='float32', mode='w+', shape=( 10000000 , 100))
    np.save( 'reg.memmap'+str(i) , numpyMemmap )
    del numpyMemmap
    os.remove( 'reg.memmap'+str(i) )

# Check if they load correctly with np.load.
NPYmemmap = []
for i in range(4):
    print(i)
    NPYmemmap.append( np.load( 'reg.memmap'+str(i)+'.npy' , mmap_mode = 'r+' )  )
del NPYmemmap

# allocate pinned memory storage
CPYmemmap = []
for i in range(4):
    print(i)
    CPYmemmap.append( cupy.load( 'reg.memmap'+str(i)+'.npy' , mmap_mode = 'r+' )  )
cupy.cuda.set_allocator(None)

我没有在具有这些文件大小的25GB主机内存的安装程序中对此进行测试。但是我已经用超过我GPU的设备内存的其他文件大小对其进行了测试,并且它似乎可以工作。

同样,未经彻底测试的实验性代码可能会有所不同,因此最好通过提交大量的github问题来实现此功能。而且,正如我之前提到的,从设备代码访问这种“设备内存”通常比普通cupy设备内存要慢得多。

最后,这并不是真正的“内存映射文件”,因为所有文件内容都将被加载到主机内存中,此外,这种方法“用完”主机内存。如果要访问20GB的文件,则将需要超过20GB的主机内存。只要“加载”了这些文件,就会使用20GB的主机内存。



1> Robert Crove..:

在我看来,当前cupy没有提供固定的分配器来代替普通的设备内存分配器,即可以用作固定的分配器cupy.ndarray。如果这对您很重要,那么您可以考虑提出一个冒号的问题。

但是,似乎可以创建一个。这应视为实验代码。并且有一些与其使用相关的问题。

基本思想是,我们将使用cupy.cuda.set_allocator已经建议的方式,用我们自己的来替换cupy的默认设备内存分配器。我们需要提供自己的替代品,以BaseMemory用作的存储库cupy.cuda.memory.MemoryPointer。此处的主要区别在于,我们将使用固定的内存分配器而不是设备分配器。这是PMemory以下课程的要点。

需要注意的其他事项:

在使用固定的内存(分配)完成所需的操作之后,您可能应该将cupy分配器恢复为其默认值。不幸的是,与不同cupy.cuda.set_allocator,我没有找到对应的cupy.cuda.get_allocator,这使我感到不足cupy,这似乎也值得向我提出杯状问题。但是,对于本演示,我们将仅返回到None使用默认设备内存分配器之一的选择(但是不使用池分配器)。

通过提供这种最小的固定内存分配器,我们仍然建议cupy这是普通的设备内存。这意味着不能直接从宿主代码访问它(实际上,但是cupy不知道)。因此,各种操作(例如cupy.load)将创建不需要的主机分配和不需要的复制操作。我认为解决这个问题将需要的不仅是我建议的小改变。但至少对于您的测试用例,此额外开销可能是可管理的。看来您想一次从磁盘加载数据,然后将其保留在那里。对于这种类型的活动,这应该是可管理的,尤其是因为您将其分为多个部分。就像我们将看到的那样,对于25GB的主机内存来说,处理四个5GB的块实在太多了。我们将需要为四个5GB块(实际上是固定的)分配主机内存,并且还需要一个额外的5GB“开销”缓冲区的额外空间。因此25GB不足以实现这一目标。但是出于演示目的,

与cupy的默认设备内存分配器关联的普通设备内存与特定设备有关联。固定的内存不必具有这样的关联,但是BaseMemory用类似的类对我们的琐碎替换意味着我们建议cupy该“设备”内存与所有其他普通的设备内存一样,具有特定的设备关联。在您这样的单个设备设置中,这种区别是没有意义的。但是,这不适用于固定内存的强大多设备使用。为此,再次建议cupy是通过提出问题来对进行更有效的更改。

这是一个例子:

import os
import numpy as np
import cupy



class PMemory(cupy.cuda.memory.BaseMemory):
    def __init__(self, size):
        self.size = size
        self.device_id = cupy.cuda.device.get_device_id()
        self.ptr = 0
        if size > 0:
            self.ptr = cupy.cuda.runtime.hostAlloc(size, 0)
    def __del__(self):
        if self.ptr:
            cupy.cuda.runtime.freeHost(self.ptr)

def my_pinned_allocator(bsize):
    return cupy.cuda.memory.MemoryPointer(PMemory(bsize),0)

cupy.cuda.set_allocator(my_pinned_allocator)

#Create 4 .npy files, ~4GB each
for i in range(4):
    print(i)
    numpyMemmap = np.memmap( 'reg.memmap'+str(i), dtype='float32', mode='w+', shape=( 10000000 , 100))
    np.save( 'reg.memmap'+str(i) , numpyMemmap )
    del numpyMemmap
    os.remove( 'reg.memmap'+str(i) )

# Check if they load correctly with np.load.
NPYmemmap = []
for i in range(4):
    print(i)
    NPYmemmap.append( np.load( 'reg.memmap'+str(i)+'.npy' , mmap_mode = 'r+' )  )
del NPYmemmap

# allocate pinned memory storage
CPYmemmap = []
for i in range(4):
    print(i)
    CPYmemmap.append( cupy.load( 'reg.memmap'+str(i)+'.npy' , mmap_mode = 'r+' )  )
cupy.cuda.set_allocator(None)

我没有在具有这些文件大小的25GB主机内存的安装程序中对此进行测试。但是我已经用超过我GPU的设备内存的其他文件大小对其进行了测试,并且它似乎可以工作。

同样,未经彻底测试的实验性代码可能会有所不同,因此最好通过提交大量的github问题来实现此功能。而且,正如我之前提到的,从设备代码访问这种“设备内存”通常比普通cupy设备内存要慢得多。

最后,这并不是真正的“内存映射文件”,因为所有文件内容都将被加载到主机内存中,此外,这种方法“用完”主机内存。如果要访问20GB的文件,则将需要超过20GB的主机内存。只要“加载”了这些文件,就会使用20GB的主机内存。


推荐阅读
  • Explore a common issue encountered when implementing an OAuth 1.0a API, specifically the inability to encode null objects and how to resolve it. ... [详细]
  • PHP 5.2.5 安装与配置指南
    本文详细介绍了 PHP 5.2.5 的安装和配置步骤,帮助开发者解决常见的环境配置问题,特别是上传图片时遇到的错误。通过本教程,您可以顺利搭建并优化 PHP 运行环境。 ... [详细]
  • 本文详细介绍了Java编程语言中的核心概念和常见面试问题,包括集合类、数据结构、线程处理、Java虚拟机(JVM)、HTTP协议以及Git操作等方面的内容。通过深入分析每个主题,帮助读者更好地理解Java的关键特性和最佳实践。 ... [详细]
  • Android LED 数字字体的应用与实现
    本文介绍了一种适用于 Android 应用的 LED 数字字体(digital font),并详细描述了其在 UI 设计中的应用场景及其实现方法。这种字体常用于视频、广告倒计时等场景,能够增强视觉效果。 ... [详细]
  • RecyclerView初步学习(一)
    RecyclerView初步学习(一)ReCyclerView提供了一种插件式的编程模式,除了提供ViewHolder缓存模式,还可以自定义动画,分割符,布局样式,相比于传统的ListVi ... [详细]
  • 扫描线三巨头 hdu1928hdu 1255  hdu 1542 [POJ 1151]
    学习链接:http:blog.csdn.netlwt36articledetails48908031学习扫描线主要学习的是一种扫描的思想,后期可以求解很 ... [详细]
  • 本文详细介绍了如何在 Spring Boot 应用中通过 @PropertySource 注解读取非默认配置文件,包括配置文件的创建、映射类的设计以及确保 Spring 容器能够正确加载这些配置的方法。 ... [详细]
  • This document outlines the recommended naming conventions for HTML attributes in Fast Components, focusing on readability and consistency with existing standards. ... [详细]
  • 本文详细介绍了Java中org.w3c.dom.Text类的splitText()方法,通过多个代码示例展示了其实际应用。该方法用于将文本节点在指定位置拆分为两个节点,并保持在文档树中。 ... [详细]
  • 本文详细介绍了 Apache Jena 库中的 Txn.executeWrite 方法,通过多个实际代码示例展示了其在不同场景下的应用,帮助开发者更好地理解和使用该方法。 ... [详细]
  • 在现代网络环境中,两台计算机之间的文件传输需求日益增长。传统的FTP和SSH方式虽然有效,但其配置复杂、步骤繁琐,难以满足快速且安全的传输需求。本文将介绍一种基于Go语言开发的新一代文件传输工具——Croc,它不仅简化了操作流程,还提供了强大的加密和跨平台支持。 ... [详细]
  • 题目Link题目学习link1题目学习link2题目学习link3%%%受益匪浅!-----&# ... [详细]
  • 解决微信电脑版无法刷朋友圈问题:使用安卓远程投屏方案
    在工作期间想要浏览微信和朋友圈却不太方便?虽然微信电脑版目前不支持直接刷朋友圈,但通过远程投屏技术,可以轻松实现在电脑上操作安卓设备的功能。 ... [详细]
  • 网络运维工程师负责确保企业IT基础设施的稳定运行,保障业务连续性和数据安全。他们需要具备多种技能,包括搭建和维护网络环境、监控系统性能、处理突发事件等。本文将探讨网络运维工程师的职业前景及其平均薪酬水平。 ... [详细]
  • 从零开始构建完整手机站:Vue CLI 3 实战指南(第一部分)
    本系列教程将引导您使用 Vue CLI 3 构建一个功能齐全的移动应用。我们将深入探讨项目中涉及的每一个知识点,并确保这些内容与实际工作中的需求紧密结合。 ... [详细]
author-avatar
陈家小女u
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有