色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

虛擬內存管理API提供管理統一虛擬地址空間的方法

星星科技指導員 ? 來源:NVIDIA ? 作者:Ken He ? 2022-04-28 09:22 ? 次閱讀

E.1. Introduction

虛擬內存管理 API 為應用程序提供了一種直接管理統一虛擬地址空間的方法,該空間由 CUDA 提供,用于將物理內存映射到 GPU 可訪問的虛擬地址。在 CUDA 10.2 中引入的這些 API 還提供了一種與其他進程和圖形 API(如 OpenGL 和 Vulkan)進行互操作的新方法,并提供了用戶可以調整以適應其應用程序的更新內存屬性。

從歷史上看,CUDA 編程模型中的內存分配調用(例如 cudaMalloc)返回了一個指向 GPU 內存的內存地址。這樣獲得的地址可以與任何 CUDA API 一起使用,也可以在設備內核中使用。但是,分配的內存無法根據用戶的內存需求調整大小。為了增加分配的大小,用戶必須顯式分配更大的緩沖區,從初始分配中復制數據,釋放它,然后繼續跟蹤新分配的地址。這通常會導致應用程序的性能降低和峰值內存利用率更高。本質上,用戶有一個類似 malloc 的接口來分配 GPU 內存,但沒有相應的 realloc 來補充它。虛擬內存管理 API 將地址和內存的概念解耦,并允許應用程序分別處理它們。 API 允許應用程序在他們認為合適的時候從虛擬地址范圍映射和取消映射內存。

在通過 cudaEnablePeerAccess 啟用對等設備訪問內存分配的情況下,所有過去和未來的用戶分配都映射到目標對等設備。這導致用戶無意中支付了將所有 cudaMalloc 分配映射到對等設備的運行時成本。然而,在大多數情況下,應用程序通過僅與另一個設備共享少量分配進行通信,并且并非所有分配都需要映射到所有設備。使用虛擬內存管理,應用程序可以專門選擇某些分配可從目標設備訪問。

CUDA 虛擬內存管理 API 向用戶提供細粒度控制,以管理應用程序中的 GPU 內存。它提供的 API 允許用戶:

將分配在不同設備上的內存放入一個連續的 VA 范圍內。

使用平臺特定機制執行內存共享的進程間通信。

在支持它們的設備上選擇更新的內存類型。

為了分配內存,虛擬內存管理編程模型公開了以下功能:

分配物理內存。

保留 VA 范圍。

將分配的內存映射到 VA 范圍。

控制映射范圍的訪問權限。

請注意,本節中描述的 API 套件需要支持 UVA 的系統。

E.2. Query for support

在嘗試使用虛擬內存管理 API 之前,應用程序必須確保他們希望使用的設備支持 CUDA 虛擬內存管理。 以下代碼示例顯示了查詢虛擬內存管理支持:

int deviceSupportsVmm;
CUresult result = cuDeviceGetAttribute(&deviceSupportsVmm, CU_DEVICE_ATTRIBUTE_VIRTUAL_MEMORY_MANAGEMENT_SUPPORTED, device);
if (deviceSupportsVmm != 0) {
    // `device` supports Virtual Memory Management 
}
   

E.3. Allocating Physical Memory

通過虛擬內存管理 API 進行內存分配的第一步是創建一個物理內存塊,為分配提供支持。 為了分配物理內存,應用程序必須使用 cuMemCreate API。 此函數創建的分配沒有任何設備或主機映射。 函數參數 CUmemGenericAllocationHandle 描述了要分配的內存的屬性,例如分配的位置、分配是否要共享給另一個進程(或其他圖形 API),或者要分配的內存的物理屬性。 用戶必須確保請求分配的大小必須與適當的粒度對齊。 可以使用 cuMemGetAllocationGranularity 查詢有關分配粒度要求的信息。 以下代碼片段顯示了使用 cuMemCreate 分配物理內存:

CUmemGenericAllocationHandle allocatePhysicalMemory(int device, size_t size) {
    CUmemAllocationProp prop = {};
    prop.type = CU_MEM_ALLOCATION_TYPE_PINNED;
    prop.location.type = CU_MEM_LOCATION_TYPE_DEVICE;
    prop.location.id = device;
    cuMemGetAllocationGranularity(&granularity, &prop, CU_MEM_ALLOC_GRANULARITY_MINIMUM);

    // Ensure size matches granularity requirements for the allocation
    size_t padded_size = ROUND_UP(size, granularity);

    // Allocate physical memory
    CUmemGenericAllocationHandle allocHandle;
    cuMemCreate(&allocHandle, padded_size, &prop, 0);

    return allocHandle;
}
   

由 cuMemCreate 分配的內存由它返回的 CUmemGenericAllocationHandle 引用。 這與 cudaMalloc風格的分配不同,后者返回一個指向 GPU 內存的指針,該指針可由在設備上執行的 CUDA 內核直接訪問。 除了使用 cuMemGetAllocationPropertiesFromHandle 查詢屬性之外,分配的內存不能用于任何操作。 為了使此內存可訪問,應用程序必須將此內存映射到由 cuMemAddressReserve 保留的 VA 范圍,并為其提供適當的訪問權限。 應用程序必須使用 cuMemRelease API 釋放分配的內存。

E.3.1. Shareable Memory Allocations

使用 cuMemCreate 用戶現在可以在分配時向 CUDA 指示他們已指定特定分配用于進程間通信或圖形互操作目的。應用程序可以通過將 CUmemAllocationProp::requestedHandleTypes 設置為平臺特定字段來完成此操作。在 Windows 上,當 CUmemAllocationProp::requestedHandleTypes 設置為 CU_MEM_HANDLE_TYPE_WIN32 時,應用程序還必須在 CUmemAllocationProp::win32HandleMetaData 中指定 LPSECURITYATTRIBUTES 屬性。該安全屬性定義了可以將導出的分配轉移到其他進程的范圍。

CUDA 虛擬內存管理 API 函數不支持傳統的進程間通信函數及其內存。相反,它們公開了一種利用操作系統特定句柄的進程間通信的新機制。應用程序可以使用 cuMemExportToShareableHandle 獲取與分配相對應的這些操作系統特定句柄。這樣獲得的句柄可以通過使用通常的 OS 本地機制進行傳輸,以進行進程間通信。接收進程應使用 cuMemImportFromShareableHandle 導入分配。

用戶必須確保在嘗試導出使用 cuMemCreate 分配的內存之前查詢是否支持請求的句柄類型。以下代碼片段說明了以特定平臺方式查詢句柄類型支持。

int deviceSupportsIpcHandle;
#if defined(__linux__)
    cuDeviceGetAttribute(&deviceSupportsIpcHandle, CU_DEVICE_ATTRIBUTE_HANDLE_TYPE_POSIX_FILE_DESCRIPTOR_SUPPORTED, device));
#else
    cuDeviceGetAttribute(&deviceSupportsIpcHandle, CU_DEVICE_ATTRIBUTE_HANDLE_TYPE_WIN32_HANDLE_SUPPORTED, device));
#endif

用戶應適當設置CUmemAllocationProp::requestedHandleTypes,如下所示:

#if defined(__linux__)
    prop.requestedHandleTypes = CU_MEM_HANDLE_TYPE_POSIX_FILE_DESCRIPTOR;
#else
    prop.requestedHandleTypes = CU_MEM_HANDLE_TYPE_WIN32;
    prop.win32HandleMetaData = // Windows specific LPSECURITYATTRIBUTES attribute.
#endif

memMapIpcDrv 示例可用作將 IPC 與虛擬內存管理分配一起使用的示例。

E.3.2. Memory Type

在 CUDA 10.2 之前,應用程序沒有用戶控制的方式來分配某些設備可能支持的任何特殊類型的內存。 使用 cuMemCreate 應用程序還可以使用 CUmemAllocationProp::allocFlags 指定內存類型要求,以選擇任何特定的內存功能。 應用程序還必須確保分配設備支持請求的內存類型。

E.3.2.1. Compressible Memory

可壓縮內存可用于加速對具有非結構化稀疏性和其他可壓縮數據模式的數據的訪問。 壓縮可以節省 DRAM 帶寬、L2 讀取帶寬和 L2 容量,具體取決于正在操作的數據。 想要在支持計算數據壓縮的設備上分配可壓縮內存的應用程序可以通過將 CUmemAllocationProp::allocFlags::compressionType 設置為 CU_MEM_ALLOCATION_COMP_GENERIC 來實現。 用戶必須通過 CU_DEVICE_ATTRIBUTE_GENERIC_COMPRESSION_SUPPORTED 查詢設備是否支持計算數據壓縮。 以下代碼片段說明了查詢可壓縮內存支持 cuDeviceGetAttribute。

int compressionSupported = 0;
cuDeviceGetAttribute(&compressionSupported, CU_DEVICE_ATTRIBUTE_GENERIC_COMPRESSION_SUPPORTED, device);

在支持計算數據壓縮的設備上,用戶需要在分配時選擇加入,如下所示:

prop.allocFlags.compressionType = CU_MEM_ALLOCATION_COMP_GENERIC;

由于硬件資源有限等各種原因,分配的內存可能沒有壓縮屬性,用戶需要使用cuMemGetAllocationPropertiesFromHandle查詢回分配內存的屬性并檢查壓縮屬性。

CUmemAllocationPropPrivate allocationProp = {};
cuMemGetAllocationPropertiesFromHandle(&allocationProp, allocationHandle);

if (allocationProp.allocFlags.compressionType == CU_MEM_ALLOCATION_COMP_GENERIC)
{
    // Obtained compressible memory allocation
}

E.4. Reserving a Virtual Address Range

由于使用虛擬內存管理,地址和內存的概念是不同的,因此應用程序必須劃出一個地址范圍,以容納由 cuMemCreate 進行的內存分配。保留的地址范圍必須至少與用戶計劃放入其中的所有物理內存分配大小的總和一樣大。

應用程序可以通過將適當的參數傳遞給 cuMemAddressReserve 來保留虛擬地址范圍。獲得的地址范圍不會有任何與之關聯的設備或主機物理內存。保留的虛擬地址范圍可以映射到屬于系統中任何設備的內存塊,從而為應用程序提供由屬于不同設備的內存支持和映射的連續 VA 范圍。應用程序應使用 cuMemAddressFree 將虛擬地址范圍返回給 CUDA。用戶必須確保在調用 cuMemAddressFree 之前未映射整個 VA 范圍。這些函數在概念上類似于 mmap/munmap(在 Linux 上)或 VirtualAlloc/VirtualFree(在 Windows 上)函數。以下代碼片段說明了該函數的用法:

CUdeviceptr ptr;
// `ptr` holds the returned start of virtual address range reserved.
CUresult result = cuMemAddressReserve(&ptr, size, 0, 0, 0); // alignment = 0 for default alignment

E.5. Virtual Aliasing Support

虛擬內存管理 API 提供了一種創建多個虛擬內存映射或“代理”到相同分配的方法,該方法使用對具有不同虛擬地址的 cuMemMap 的多次調用,即所謂的虛擬別名。 除非在 PTX ISA 中另有說明,否則寫入分配的一個代理被認為與同一內存的任何其他代理不一致和不連貫,直到寫入設備操作(網格啟動、memcpy、memset 等)完成。 在寫入設備操作之前出現在 GPU 上但在寫入設備操作完成后讀取的網格也被認為具有不一致和不連貫的代理。

例如,下面的代碼片段被認為是未定義的,假設設備指針 A 和 B 是相同內存分配的虛擬別名:

__global__ void foo(char *A, char *B) {
  *A = 0x1;
  printf(“%d\n”, *B);    // Undefined behavior!  *B can take on either
// the previous value or some value in-between.
}

以下是定義的行為,假設這兩個內核是單調排序的(通過流或事件)。

__global__ void foo1(char *A) {
  *A = 0x1;
}

__global__ void foo2(char *B) {
  printf(“%d\n”, *B);    // *B == *A == 0x1 assuming foo2 waits for foo1
// to complete before launching
}

cudaMemcpyAsync(B, input, size, stream1);    // Aliases are allowed at
// operation boundaries
foo1<<<1,1,0,stream1>>>(A);                  // allowing foo1 to access A.
cudaEventRecord(event, stream1);
cudaStreamWaitEvent(stream2, event);
foo2<<<1,1,0,stream2>>>(B);
cudaStreamWaitEvent(stream3, event);
cudaMemcpyAsync(output, B, size, stream3);  // Both launches of foo2 and
                                            // cudaMemcpy (which both
                                            // read) wait for foo1 (which writes)
                                            // to complete before proceeding

E.6. Mapping Memory

前兩節分配的物理內存和挖出的虛擬地址空間代表了虛擬內存管理 API 引入的內存和地址區別。為了使分配的內存可用,用戶必須首先將內存放在地址空間中。從 cuMemAddressReserve 獲取的地址范圍和從 cuMemCreate 或 cuMemImportFromShareableHandle 獲取的物理分配必須通過 cuMemMap 相互關聯。

用戶可以關聯來自多個設備的分配以駐留在連續的虛擬地址范圍內,只要他們已經劃分出足夠的地址空間。為了解耦物理分配和地址范圍,用戶必須通過 cuMemUnmap 取消映射的地址。用戶可以根據需要多次將內存映射和取消映射到同一地址范圍,只要他們確保不會嘗試在已映射的 VA 范圍保留上創建映射。以下代碼片段說明了該函數的用法:

CUdeviceptr ptr;
// `ptr`: address in the address range previously reserved by cuMemAddressReserve.
// `allocHandle`: CUmemGenericAllocationHandle obtained by a previous call to cuMemCreate. 
CUresult result = cuMemMap(ptr, size, 0, allocHandle, 0);

E.7. Control Access Rights

虛擬內存管理 API 使應用程序能夠通過訪問控制機制顯式保護其 VA 范圍。 使用 cuMemMap 將分配映射到地址范圍的區域不會使地址可訪問,并且如果被 CUDA 內核訪問會導致程序崩潰。 用戶必須使用 cuMemSetAccess 函數專門選擇訪問控制,該函數允許或限制特定設備對映射地址范圍的訪問。 以下代碼片段說明了該函數的用法:

void setAccessOnDevice(int device, CUdeviceptr ptr, size_t size) {
    CUmemAccessDesc accessDesc = {};
    accessDesc.location.type = CU_MEM_LOCATION_TYPE_DEVICE;
    accessDesc.location.id = device;
    accessDesc.flags = CU_MEM_ACCESS_FLAGS_PROT_READWRITE;

    // Make the address accessible
    cuMemSetAccess(ptr, size, &accessDesc, 1);
}

使用虛擬內存管理公開的訪問控制機制允許用戶明確他們希望與系統上的其他對等設備共享哪些分配。 如前所述,cudaEnablePeerAccess 強制將所有先前和將來的 cudaMalloc 分配映射到目標對等設備。 這在許多情況下很方便,因為用戶不必擔心跟蹤每個分配到系統中每個設備的映射狀態。 但是對于關心其應用程序性能的用戶來說,這種方法具有性能影響。 通過分配粒度的訪問控制,虛擬內存管理公開了一種機制,可以以最小的開銷進行對等映射。

關于作者

Ken He 是 NVIDIA 企業級開發者社區經理 & 高級講師,擁有多年的 GPU 和人工智能開發經驗。自 2017 年加入 NVIDIA 開發者社區以來,完成過上百場培訓,幫助上萬個開發者了解人工智能和 GPU 編程開發。在計算機視覺,高性能計算領域完成過多個獨立項目。并且,在機器人無人機領域,有過豐富的研發經驗。對于圖像識別,目標的檢測與跟蹤完成過多種解決方案。曾經參與 GPU 版氣象模式GRAPES,是其主要研發者。

審核編輯:郭婷

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • gpu
    gpu
    +關注

    關注

    28

    文章

    4753

    瀏覽量

    129057
  • API
    API
    +關注

    關注

    2

    文章

    1505

    瀏覽量

    62168
  • CUDA
    +關注

    關注

    0

    文章

    121

    瀏覽量

    13642
收藏 人收藏

    評論

    相關推薦

    虛擬電廠如何接入新型電力微電網管理系統?

    統一運營和優化控制的虛擬化電力系統,實現能源的高效利用和協同配合。 微電網管理系統概述 微電網(Micro-Grid)也稱為微網,是指由分布式電源、儲能裝置、能量轉換裝置、負荷、監控和保護裝置等組成的小型發配電系統。微電網
    的頭像 發表于 12-20 09:05 ?122次閱讀
    <b class='flag-5'>虛擬</b>電廠如何接入新型電力微電網<b class='flag-5'>管理</b>系統?

    虛擬內存和云計算的關系

    在現代計算機科學中,虛擬內存和云計算是兩個關鍵的技術概念。虛擬內存內存管理技術,它允許計算機使用比物理
    的頭像 發表于 12-04 09:50 ?134次閱讀

    虛擬內存溢出該怎么處理 虛擬內存在服務器中的應用

    在現代計算機系統中,虛擬內存種重要的資源管理技術,它允許系統使用硬盤空間來擴展物理內存的容量。然而,當系統運行的程序和進程超出了物理
    的頭像 發表于 12-04 09:49 ?187次閱讀

    Linux下如何管理虛擬內存 使用虛擬內存時的常見問題

    在Linux系統中,虛擬內存管理是操作系統內核的個重要功能,負責管理物理內存和磁盤上的交換空間
    的頭像 發表于 12-04 09:19 ?488次閱讀

    虛擬內存對計算機性能的影響

    在現代計算機系統中,內存管理是確保系統高效運行的關鍵因素之。虛擬內存技術作為內存管理的核心組成
    的頭像 發表于 12-04 09:17 ?878次閱讀

    什么是虛擬內存分頁 Windows系統虛擬內存優化方法

    虛擬內存分頁概述 在Windows操作系統中,虛擬內存是通過分頁機制實現的。分頁允許系統將內存中的數據移動到硬盤上,以便為當前運行的程序騰出空間。這個過程對于保持系統的流暢運行至關重要
    的頭像 發表于 12-04 09:16 ?418次閱讀

    虛擬內存不足如何解決 虛擬內存和物理內存的區別

    虛擬內存不足的解決方案 虛擬內存不足是計算機用戶經常遇到的問題,尤其是在運行大型軟件或多任務處理時。以下是些解決虛擬內存不足問題的方法
    的頭像 發表于 12-04 09:14 ?471次閱讀

    虛擬內存的作用和原理 如何調整虛擬內存設置

    虛擬內存,也稱為虛擬內存管理或頁面文件,是計算機操作系統中的內存管理技術。它允許系統使用硬盤
    的頭像 發表于 12-04 09:13 ?519次閱讀

    如何優化RAM內存使用

    :使用任務管理器查看當前運行的程序和服務,關閉那些不需要的。 禁用啟動程序 :減少開機啟動項,只保留必要的程序。 2. 優化操作系統設置 調整虛擬內存 :合理設置虛擬內存,避免過多占用硬盤
    的頭像 發表于 11-11 09:58 ?427次閱讀

    基于DPU的輕量虛擬化解決方案

    機上都會運行宿主機以及虛擬化的系統軟件。這些系統軟件負責為用戶提供虛擬的計算環境,包括虛擬CPU、虛擬內存、
    的頭像 發表于 10-14 14:57 ?926次閱讀
    基于DPU的輕量<b class='flag-5'>虛擬</b>化解決方案

    Windows管理內存的三種主要方式

    Windows操作系統提供了多種方式來管理內存,以確保系統資源的有效利用和性能的優化。以下是關于Windows管理內存的三種主要方式的詳細闡
    的頭像 發表于 10-12 17:09 ?950次閱讀

    華納云:OpenStack是虛擬管理平臺嗎?其工作原理是什么?

    OpenStack 就是虛擬管理平臺嗎?這樣說并不準確。它們存在很多相似性,但并非完全相同。的確,OpenStack 和虛擬管理平臺
    的頭像 發表于 09-23 14:20 ?342次閱讀

    華為專利公布:內存管理方法及相關設備

    該專利主要講述如何通過特定方法優化內存管理效率,包括確定N個具有相同虛擬地址但權限各異的進程(N必須為大于或等于2的整數),并據此建立特定映射關系表以及權限表,每
    的頭像 發表于 04-16 09:51 ?448次閱讀
    華為專利公布:<b class='flag-5'>內存</b><b class='flag-5'>管理方法</b>及相關設備

    虛擬機的ip地址和主機樣嗎

    虛擬機的ip地址和主機樣嗎? 虛擬機的IP地址和主機的IP地址通常不相同。
    的頭像 發表于 03-26 15:34 ?5416次閱讀

    拆解mmap內存映射的本質!

    mmap 內存映射里所謂的內存其實指的是虛擬內存,在調用 mmap 進行匿名映射的時候(比如進行堆內存的分配),是將進程虛擬內存空間中的某
    的頭像 發表于 01-24 14:30 ?1807次閱讀
    拆解mmap<b class='flag-5'>內存</b>映射的本質!
    主站蜘蛛池模板: 亚洲日韩欧美国产专区| 沈阳熟女露脸对白视频| 亚洲 欧美 中文字幕 在线| 国产精品久久vr专区| 性欧美xxxxporn| 精子射到丝袜上图| 999久久久无码国产精蜜柚| 欧美xxbb| 国产精品99久久免费黑人人妻| 午夜神器老司机高清无码| 欧美性爱-第1页| 国产电影一区二区三区| 亚洲久久少妇中文字幕| 嫩小幼处在线| yellow日本动漫免费观看| 色裕插插插影视| 久久999视频| 超熟女专门志| 亚洲一区免费香蕉在线| 青青青草免费| 狠狠色欧美亚洲狠狠色www| 中国老头oldday tv| 欧美zzzoooxxx| 和姐姐做插得很深| 超碰97免费人妻| 一个色夫导航| 手机毛片在线观看| 久青草国产97香蕉在线视频| 闺蜜扒开我尿口使劲揉| 做i爱视频30分钟免费| 丝袜诱惑qvod| 里番※琉璃全彩acg奈亚子| 动漫美女3d被爆漫画| 亚婷婷洲AV久久蜜臀无码| 奇米狠狠干| 久久国产精品高清一区二区三区| 大胸美女脱内衣黄网站| 长泽梓黑人初解禁bdd07| 青青草原成人| 浪荡女天天不停挨CAO日常视| www.久艹|