91在线观看视频-91在线观看视频-91在线观看免费视频-91在线观看免费-欧美第二页-欧美第1页

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

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

3天內不再提示

分配器支持在進程間輕松安全地共享分配

星星科技指導員 ? 來源:NVIDIA ? 作者:Ken He ? 2022-04-28 09:42 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

F.1. Introduction

使用 cudaMalloc 和 cudaFree 管理內存分配會導致 GPU 在所有正在執行的 CUDA 流之間進行同步。 Stream Order Memory Allocator 使應用程序能夠通過啟動到 CUDA 流中的其他工作(例如內核啟動和異步拷貝)來對內存分配和釋放進行排序。這通過利用流排序語義來重用內存分配來改進應用程序內存使用。分配器還允許應用程序控制分配器的內存緩存行為。當設置了適當的釋放閾值時,緩存行為允許分配器在應用程序表明它愿意接受更大的內存占用時避免對操作系統進行昂貴的調用。分配器還支持在進程之間輕松安全地共享分配。

對于許多應用程序,Stream Ordered Memory Allocator 減少了對自定義內存管理抽象的需求,并使為需要它的應用程序創建高性能自定義內存管理變得更加容易。對于已經具有自定義內存分配器的應用程序和庫,采用 Stream Ordered Memory Allocator 可以使多個庫共享由驅動程序管理的公共內存池,從而減少過多的內存消耗。此外,驅動程序可以根據其對分配器和其他流管理 API 的感知執行優化。最后,Nsight Compute 和 Next-Gen CUDA 調試器知道分配器是其 CUDA 11.3 工具包支持的一部分。

F.2. Query for Support

用戶可以通過使用設備屬性 cudaDevAttrMemoryPoolsSupported 調用 cudaDeviceGetAttribute() 來確定設備是否支持流序內存分配器。

從 CUDA 11.3 開始,可以使用 cudaDevAttrMemoryPoolSupportedHandleTypes 設備屬性查詢 IPC 內存池支持。 以前的驅動程序將返回 cudaErrorInvalidValue,因為這些驅動程序不知道屬性枚舉。

int driverVersion = 0;
int deviceSupportsMemoryPools = 0;
int poolSupportedHandleTypes = 0;
cudaDriverGetVersion(&driverVersion);
if (driverVersion >= 11020) {
    cudaDeviceGetAttribute(&deviceSupportsMemoryPools,
                           cudaDevAttrMemoryPoolsSupported, device);
}
if (deviceSupportsMemoryPools != 0) {
    // `device` supports the Stream Ordered Memory Allocator
}

if (driverVersion >= 11030) {
    cudaDeviceGetAttribute(&poolSupportedHandleTypes,
              cudaDevAttrMemoryPoolSupportedHandleTypes, device);
}
if (poolSupportedHandleTypes & cudaMemHandleTypePosixFileDescriptor) {
   // Pools on the specified device can be created with posix file descriptor-based IPC
}

在查詢之前執行驅動程序版本檢查可避免在尚未定義屬性的驅動程序上遇到 cudaErrorInvalidValue 錯誤。 可以使用 cudaGetLastError 來清除錯誤而不是避免它。

F.3. API Fundamentals (cudaMallocAsync and cudaFreeAsync)

API cudaMallocAsync 和 cudaFreeAsync 構成了分配器的核心。 cudaMallocAsync 返回分配,cudaFreeAsync 釋放分配。 兩個 API 都接受流參數來定義分配何時變為可用和停止可用。 cudaMallocAsync 返回的指針值是同步確定的,可用于構建未來的工作。 重要的是要注意 cudaMallocAsync 在確定分配的位置時會忽略當前設備/上下文。 相反,cudaMallocAsync 根據指定的內存池或提供的流來確定常駐設備。 最簡單的使用模式是分配、使用和釋放內存到同一個流中。

void *ptr;
size_t size = 512;
cudaMallocAsync(&ptr, size, cudaStreamPerThread);
// do work using the allocation
kernel<<<..., cudaStreamPerThread>>>(ptr, ...);
// An asynchronous free can be specified without synchronizing the CPU and GPU
cudaFreeAsync(ptr, cudaStreamPerThread);

用戶可以使用cudaFreeAsync()釋放使用cudaMalloc()分配的內存。 在自由操作開始之前,用戶必須對訪問完成做出同樣的保證。

cudaMalloc(&ptr, size);
kernel<<<..., stream>>>(ptr, ...);
cudaFreeAsync(ptr, stream);

用戶可以使用cudaFree()釋放使用cudaMallocAsync分配的內存。 通過cudaFree()API 釋放此類分配時,驅動程序假定對分配的所有訪問都已完成,并且不執行進一步的同步。 用戶可以使用cudaStreamQuery / cudaStreamSynchronize / cudaEventQuery / cudaEventSynchronize / cudaDeviceSynchronize來保證適當的異步工作完成并且GPU不會嘗試訪問分配。

cudaMallocAsync(&ptr, size,stream);
kernel<<<..., stream>>>(ptr, ...);
// synchronize is needed to avoid prematurely freeing the memory
cudaStreamSynchronize(stream);
cudaFree(ptr);

F.4. Memory Pools and the cudaMemPool_t

內存池封裝了虛擬地址和物理內存資源,根據內存池的屬性和屬性進行分配和管理。內存池的主要方面是它所管理的內存的種類和位置。

所有對 cudaMallocAsync 的調用都使用內存池的資源。在沒有指定內存池的情況下,cudaMallocAsync API 使用提供的流設備的當前內存池。設備的當前內存池可以使用 cudaDeviceSetMempool 設置并使用 cudaDeviceGetMempool 查詢。默認情況下(在沒有 cudaDeviceSetMempool 調用的情況下),當前內存池是設備的默認內存池。 cudaMallocFromPoolAsync 的 API cudaMallocFromPoolAsync 和 c++ 重載允許用戶指定要用于分配的池,而無需將其設置為當前池。 API cudaDeviceGetDefaultMempool 和 cudaMemPoolCreate 為用戶提供內存池的句柄。

注意:設備的內存池當前將是該設備的本地。因此,在不指定內存池的情況下進行分配將始終產生流設備本地的分配。

注意:cudaMemPoolSetAttribute 和 cudaMemPoolGetAttribute 控制內存池的屬性。

F.5. Default/Impicit Pools

可以使用 cudaDeviceGetDefaultMempool API 檢索設備的默認內存池。 來自設備默認內存池的分配是位于該設備上的不可遷移設備分配。 這些分配將始終可以從該設備訪問。 默認內存池的可訪問性可以通過 cudaMemPoolSetAccess 進行修改,并通過 cudaMemPoolGetAccess 進行查詢。 由于不需要顯式創建默認池,因此有時將它們稱為隱式池。 設備默認內存池不支持IPC。

F.6. Explicit Pools

API cudaMemPoolCreate 創建一個顯式池。 目前內存池只能分配設備分配。 分配將駐留的設備必須在屬性結構中指定。 顯式池的主要用例是 IPC 功能。

// create a pool similar to the implicit pool on device 0
int device = 0;
cudaMemPoolProps poolProps = { };
poolProps.allocType = cudaMemAllocationTypePinned;
poolProps.location.id = device;
poolProps.location.type = cudaMemLocationTypeDevice;

cudaMemPoolCreate(&memPool, &poolProps));

F.7. Physical Page Caching Behavior

默認情況下,分配器嘗試最小化池擁有的物理內存。 為了盡量減少分配和釋放物理內存的操作系統調用,應用程序必須為每個池配置內存占用。 應用程序可以使用釋放閾值屬性 (cudaMemPoolAttrReleaseThreshold) 執行此操作。

釋放閾值是池在嘗試將內存釋放回操作系統之前應保留的內存量(以字節為單位)。 當內存池持有超過釋放閾值字節的內存時,分配器將嘗試在下一次調用流、事件或設備同步時將內存釋放回操作系統。 將釋放閾值設置為 UINT64_MAX 將防止驅動程序在每次同步后嘗試收縮池。

Cuuint64_t setVal = UINT64_MAX;
cudaMemPoolSetAttribute(memPool, cudaMemPoolAttrReleaseThreshold, &setVal);

cudaMemPoolAttrReleaseThreshold設置得足夠高以有效禁用內存池收縮的應用程序可能希望顯式收縮內存池的內存占用。cudaMemPoolTrimTo允許此類應用程序這樣做。 在修剪內存池的占用空間時,minBytesToKeep參數允許應用程序保留它預期在后續執行階段需要的內存量。

Cuuint64_t setVal = UINT64_MAX;
cudaMemPoolSetAttribute(memPool, cudaMemPoolAttrReleaseThreshold, &setVal);

// application phase needing a lot of memory from the stream ordered allocator
for (i=0; i<10; i++) {
    for (j=0; j<10; j++) {
        cudaMallocAsync(&ptrs[j],size[j], stream);
    }
    kernel<<<...,stream>>>(ptrs,...);
    for (j=0; j<10; j++) {
        cudaFreeAsync(ptrs[j], stream);
    }
}

// Process does not need as much memory for the next phase.
// Synchronize so that the trim operation will know that the allocations are no 
// longer in use.
cudaStreamSynchronize(stream);
cudaMemPoolTrimTo(mempool, 0);

// Some other process/allocation mechanism can now use the physical memory 
// released by the trimming operation.

F.8. Resource Usage Statistics

在 CUDA 11.3 中,添加了池屬性 cudaMemPoolAttrReservedMemCurrent、cudaMemPoolAttrReservedMemHigh、cudaMemPoolAttrUsedMemCurrent 和 cudaMemPoolAttrUsedMemHigh 來查詢池的內存使用情況。

查詢池的 cudaMemPoolAttrReservedMemCurrent 屬性會報告該池當前消耗的總物理 GPU 內存。 查詢池的 cudaMemPoolAttrUsedMemCurrent 會返回從池中分配且不可重用的所有內存的總大小。

cudaMemPoolAttr*MemHigh 屬性是記錄自上次重置以來各個 cudaMemPoolAttr*MemCurrent 屬性達到的最大值的水印。 可以使用 cudaMemPoolSetAttribute API 將它們重置為當前值。

// sample helper functions for getting the usage statistics in bulk
struct usageStatistics {
    cuuint64_t reserved;
    cuuint64_t reservedHigh;
    cuuint64_t used;
    cuuint64_t usedHigh;
};

void getUsageStatistics(cudaMemoryPool_t memPool, struct usageStatistics *statistics)
{
    cudaMemPoolGetAttribute(memPool, cudaMemPoolAttrReservedMemCurrent, statistics->reserved);
    cudaMemPoolGetAttribute(memPool, cudaMemPoolAttrReservedMemHigh, statistics->reservedHigh);
    cudaMemPoolGetAttribute(memPool, cudaMemPoolAttrUsedMemCurrent, statistics->used);
    cudaMemPoolGetAttribute(memPool, cudaMemPoolAttrUsedMemHigh, statistics->usedHigh);
}


// resetting the watermarks will make them take on the current value.
void resetStatistics(cudaMemoryPool_t memPool)
{
    cuuint64_t value = 0;
    cudaMemPoolSetAttribute(memPool, cudaMemPoolAttrReservedMemHigh, &value);
    cudaMemPoolSetAttribute(memPool, cudaMemPoolAttrUsedMemHigh, &value);
}

F.9. Memory Reuse Policies

為了服務分配請求,驅動程序在嘗試從操作系統分配更多內存之前嘗試重用之前通過 cudaFreeAsync() 釋放的內存。 例如,流中釋放的內存可以立即重新用于同一流中的后續分配請求。 類似地,當一個流與 CPU 同步時,之前在該流中釋放的內存可以重新用于任何流中的分配。

流序分配器有一些可控的分配策略。 池屬性 cudaMemPoolReuseFollowEventDependencies、cudaMemPoolReuseAllowOpportunistic 和 cudaMemPoolReuseAllowInternalDependencies 控制這些策略。 升級到更新的 CUDA 驅動程序可能會更改、增強、增加或重新排序重用策略。

F.9.1. cudaMemPoolReuseFollowEventDependencies

在分配更多物理 GPU 內存之前,分配器會檢查由 CUDA 事件建立的依賴信息,并嘗試從另一個流中釋放的內存中進行分配。

cudaMallocAsync(&ptr, size, originalStream);
kernel<<<..., originalStream>>>(ptr, ...);
cudaFreeAsync(ptr, originalStream);
cudaEventRecord(event,originalStream);

// waiting on the event that captures the free in another stream 
// allows the allocator to reuse the memory to satisfy 
// a new allocation request in the other stream when
// cudaMemPoolReuseFollowEventDependencies is enabled.
cudaStreamWaitEvent(otherStream, event);
cudaMallocAsync(&ptr2, size, otherStream);

F.9.2. cudaMemPoolReuseAllowOpportunistic

根據 cudaMemPoolReuseAllowOpportunistic 策略,分配器檢查釋放的分配以查看是否滿足釋放的流序語義(即流已通過釋放指示的執行點)。 禁用此功能后,分配器仍將重用在流與 cpu 同步時可用的內存。 禁用此策略不會阻止 cudaMemPoolReuseFollowEventDependencies 應用。

cudaMallocAsync(&ptr, size, originalStream);
kernel<<<..., originalStream>>>(ptr, ...);
cudaFreeAsync(ptr, originalStream);


// after some time, the kernel finishes running
wait(10);

// When cudaMemPoolReuseAllowOpportunistic is enabled this allocation request
// can be fulfilled with the prior allocation based on the progress of originalStream.
cudaMallocAsync(&ptr2, size, otherStream);

F.9.3. cudaMemPoolReuseAllowInternalDependencies

如果無法從操作系統分配和映射更多物理內存,驅動程序將尋找其可用性取決于另一個流的待處理進度的內存。 如果找到這樣的內存,驅動程序會將所需的依賴項插入分配流并重用內存。

cudaMallocAsync(&ptr, size, originalStream);
kernel<<<..., originalStream>>>(ptr, ...);
cudaFreeAsync(ptr, originalStream);

// When cudaMemPoolReuseAllowInternalDependencies is enabled
// and the driver fails to allocate more physical memory, the driver may
// effectively perform a cudaStreamWaitEvent in the allocating stream
// to make sure that future work in ‘otherStream’ happens after the work
// in the original stream that would be allowed to access the original allocation. 
cudaMallocAsync(&ptr2, size, otherStream);

F.9.4. Disabling Reuse Policies

雖然可控重用策略提高了內存重用,但用戶可能希望禁用它們。 允許機會重用(即 cudaMemPoolReuseAllowOpportunistic)基于 CPU 和 GPU 執行的交錯引入了運行到運行分配模式的差異。 當用戶寧愿在分配失敗時顯式同步事件或流時,內部依賴插入(即 cudaMemPoolReuseAllowInternalDependencies)可以以意想不到的和潛在的非確定性方式序列化工作。

F.10. Device Accessibility for Multi-GPU Support

就像通過虛擬內存管理 API 控制的分配可訪問性一樣,內存池分配可訪問性不遵循 cudaDeviceEnablePeerAccess 或 cuCtxEnablePeerAccess。相反,API cudaMemPoolSetAccess 修改了哪些設備可以訪問池中的分配。默認情況下,可以從分配所在的設備訪問分配。無法撤銷此訪問權限。要啟用其他設備的訪問,訪問設備必須與內存池的設備對等;檢查 cudaDeviceCanAccessPeer。如果未檢查對等功能,則設置訪問可能會失敗并顯示 cudaErrorInvalidDevice。如果沒有從池中進行分配,即使設備不具備對等能力,cudaMemPoolSetAccess 調用也可能成功;在這種情況下,池中的下一次分配將失敗。

值得注意的是,cudaMemPoolSetAccess 會影響內存池中的所有分配,而不僅僅是未來的分配。此外,cudaMemPoolGetAccess 報告的可訪問性適用于池中的所有分配,而不僅僅是未來的分配。建議不要頻繁更改給定 GPU 的池的可訪問性設置;一旦池可以從給定的 GPU 訪問,它應該在池的整個生命周期內都可以從該 GPU 訪問。

// snippet showing usage of cudaMemPoolSetAccess:
cudaError_t setAccessOnDevice(cudaMemPool_t memPool, int residentDevice,
              int accessingDevice) {
    cudaMemAccessDesc accessDesc = {};
    accessDesc.location.type = cudaMemLocationTypeDevice;
    accessDesc.location.id = accessingDevice;
    accessDesc.flags = cudaMemAccessFlagsProtReadWrite;

    int canAccess = 0;
    cudaError_t error = cudaDeviceCanAccessPeer(&canAccess, accessingDevice,
              residentDevice);
    if (error != cudaSuccess) {
        return error;
    } else if (canAccess == 0) {
        return cudaErrorPeerAccessUnsupported;
    }

    // Make the address accessible
    return cudaMemPoolSetAccess(memPool, &accessDesc, 1);
}

F.11. IPC Memory Pools

支持 IPC 的內存池允許在進程之間輕松、高效和安全地共享 GPU 內存。 CUDA 的 IPC 內存池提供與 CUDA 的虛擬內存管理 API 相同的安全優勢。

在具有內存池的進程之間共享內存有兩個階段。 進程首先需要共享對池的訪問權限,然后共享來自該池的特定分配。 第一階段建立并實施安全性。 第二階段協調每個進程中使用的虛擬地址以及映射何時需要在導入過程中有效。

F.11.1. Creating and Sharing IPC Memory Pools

共享對池的訪問涉及檢索池的 OS 本機句柄(使用 cudaMemPoolExportToShareableHandle() API),使用通常的 OS 本機 IPC 機制將句柄轉移到導入進程,并創建導入的內存池(使用 cudaMemPoolImportFromShareableHandle() API)。 要使 cudaMemPoolExportToShareableHandle 成功,必須使用池屬性結構中指定的請求句柄類型創建內存池。 請參考示例以了解在進程之間傳輸操作系統本機句柄的適當 IPC 機制。 該過程的其余部分可以在以下代碼片段中找到。

// in exporting process
// create an exportable IPC capable pool on device 0
cudaMemPoolProps poolProps = { };
poolProps.allocType = cudaMemAllocationTypePinned;
poolProps.location.id = 0;
poolProps.location.type = cudaMemLocationTypeDevice;

// Setting handleTypes to a non zero value will make the pool exportable (IPC capable)
poolProps.handleTypes = CU_MEM_HANDLE_TYPE_POSIX_FILE_DESCRIPTOR;

cudaMemPoolCreate(&memPool, &poolProps));

// FD based handles are integer types
int fdHandle = 0;


// Retrieve an OS native handle to the pool.
// Note that a pointer to the handle memory is passed in here.
cudaMemPoolExportToShareableHandle(&fdHandle,
             memPool,
             CU_MEM_HANDLE_TYPE_POSIX_FILE_DESCRIPTOR,
             0);

// The handle must be sent to the importing process with the appropriate
// OS specific APIs.
// in importing process
 int fdHandle;
// The handle needs to be retrieved from the exporting process with the
// appropriate OS specific APIs.
// Create an imported pool from the shareable handle.
// Note that the handle is passed by value here. 
cudaMemPoolImportFromShareableHandle(&importedMemPool,
          (void*)fdHandle,
          CU_MEM_HANDLE_TYPE_POSIX_FILE_DESCRIPTOR,
          0);

F.11.2. Set Access in the Importing Process

導入的內存池最初只能從其常駐設備訪問。 導入的內存池不繼承導出進程設置的任何可訪問性。 導入過程需要啟用從它計劃訪問內存的任何 GPU 的訪問(使用 cudaMemPoolSetAccess)。

如果導入的內存池在導入過程中屬于不可見的設備,則用戶必須使用 cudaMemPoolSetAccess API 來啟用從將使用分配的 GPU 的訪問。

F.11.3. Creating and Sharing Allocations from an Exported Pool

共享池后,在導出進程中使用 cudaMallocAsync() 從池中進行的分配可以與已導入池的其他進程共享。由于池的安全策略是在池級別建立和驗證的,操作系統不需要額外的簿記來為特定的池分配提供安全性;換句話說,導入池分配所需的不透明 cudaMemPoolPtrExportData 可以使用任何機制發送到導入進程。

雖然分配可以在不以任何方式與分配流同步的情況下導出甚至導入,但在訪問分配時,導入過程必須遵循與導出過程相同的規則。即,對分配的訪問必須發生在分配流中分配操作的流排序之后。以下兩個代碼片段顯示 cudaMemPoolExportPointer() 和 cudaMemPoolImportPointer() 與 IPC 事件共享分配,用于保證在分配準備好之前在導入過程中不會訪問分配。

// preparing an allocation in the exporting process
cudaMemPoolPtrExportData exportData;
cudaEvent_t readyIpcEvent;
cudaIpcEventHandle_t readyIpcEventHandle;

// IPC event for coordinating between processes
// cudaEventInterprocess flag makes the event an IPC event
// cudaEventDisableTiming  is set for performance reasons

cudaEventCreate(
        &readyIpcEvent, cudaEventDisableTiming | cudaEventInterprocess)

// allocate from the exporting mem pool
cudaMallocAsync(&ptr, size,exportMemPool, stream);

// event for sharing when the allocation is ready.
cudaEventRecord(readyIpcEvent, stream);
cudaMemPoolExportPointer(&exportData, ptr);
cudaIpcGetEventHandle(&readyIpcEventHandle, readyIpcEvent);

// Share IPC event and pointer export data with the importing process using
//  any mechanism. Here we copy the data into shared memory
shmem->ptrData = exportData;
shmem->readyIpcEventHandle = readyIpcEventHandle;
// signal consumers data is ready
// Importing an allocation
cudaMemPoolPtrExportData *importData = &shmem->prtData;
cudaEvent_t readyIpcEvent;
cudaIpcEventHandle_t *readyIpcEventHandle = &shmem->readyIpcEventHandle;

// Need to retrieve the IPC event handle and the export data from the
// exporting process using any mechanism.  Here we are using shmem and just
// need synchronization to make sure the shared memory is filled in.

cudaIpcOpenEventHandle(&readyIpcEvent, readyIpcEventHandle);

// import the allocation. The operation does not block on the allocation being ready.
cudaMemPoolImportPointer(&ptr, importedMemPool, importData);

// Wait for the prior stream operations in the allocating stream to complete before
// using the allocation in the importing process.
cudaStreamWaitEvent(stream, readyIpcEvent);
kernel<<<..., stream>>>(ptr, ...);

釋放分配時,需要先在導入過程中釋放分配,然后在導出過程中釋放分配。 以下代碼片段演示了使用 CUDA IPC 事件在兩個進程中的cudaFreeAsync操作之間提供所需的同步。 導入過程中對分配的訪問顯然受到導入過程側的自由操作的限制。 值得注意的是,cudaFree可用于釋放兩個進程中的分配,并且可以使用其他流同步 API 代替 CUDA IPC 事件。

// The free must happen in importing process before the exporting process
kernel<<<..., stream>>>(ptr, ...); 

// Last access in importing process
cudaFreeAsync(ptr, stream); 

// Access not allowed in the importing process after the free
cudaIpcEventRecord(finishedIpcEvent, stream);
// Exporting process
// The exporting process needs to coordinate its free with the stream order 
// of the importing process’s free.
cudaStreamWaitEvent(stream, finishedIpcEvent);
kernel<<<..., stream>>>(ptrInExportingProcess, ...); 

// The free in the importing process doesn’t stop the exporting process 
// from using the allocation.
cudFreeAsync(ptrInExportingProcess,stream);

F.11.4. IPC Export Pool Limitations

IPC 池目前不支持將物理塊釋放回操作系統。 因此,cudaMemPoolTrimTo API 充當空操作,并且 cudaMemPoolAttrReleaseThreshold 被有效地忽略。 此行為由驅動程序控制,而不是運行時控制,并且可能會在未來的驅動程序更新中發生變化。

F.11.5. IPC Import Pool Limitations

不允許從導入池中分配; 具體來說,導入池不能設置為當前,也不能在 cudaMallocFromPoolAsync API 中使用。 因此,分配重用策略屬性對這些池沒有意義。

IPC 池目前不支持將物理塊釋放回操作系統。 因此,cudaMemPoolTrimTo API 充當空操作,并且 cudaMemPoolAttrReleaseThreshold 被有效地忽略。

資源使用統計屬性查詢僅反映導入進程的分配和相關的物理內存。

F.12. Synchronization API Actions

作為 CUDA 驅動程序一部分的分配器帶來的優化之一是與同步 API 的集成。 當用戶請求 CUDA 驅動程序同步時,驅動程序等待異步工作完成。 在返回之前,驅動程序將確定什么釋放了保證完成的同步。 無論指定的流或禁用的分配策略如何,這些分配都可用于分配。 驅動程序還在這里檢查 cudaMemPoolAttrReleaseThreshold 并釋放它可以釋放的任何多余的物理內存。

F.13. Addendums

F.13.1. cudaMemcpyAsync Current Context/Device Sensitivity

在當前的 CUDA 驅動程序中,任何涉及來自 cudaMallocAsync 的內存的異步 memcpy 都應該使用指定流的上下文作為調用線程的當前上下文來完成。 這對于 cudaMemcpyPeerAsync 不是必需的,因為引用了 API 中指定的設備主上下文而不是當前上下文。

F.13.2. cuPointerGetAttribute Query

在對分配調用 cudaFreeAsync 后在分配上調用 cuPointerGetAttribute 會導致未定義的行為。 具體來說,分配是否仍然可以從給定的流中訪問并不重要:行為仍然是未定義的。

F.13.3. cuGraphAddMemsetNode

cuGraphAddMemsetNode 不適用于通過流排序分配器分配的內存。 但是,分配的 memset 可以被流捕獲。

F.13.4. Pointer Attributes

cuPointerGetAttributes 查詢適用于流有序分配。 由于流排序分配與上下文無關,因此查詢 CU_POINTER_ATTRIBUTE_CONTEXT 將成功,但在 *data 中返回 NULL。 屬性 CU_POINTER_ATTRIBUTE_DEVICE_ORDINAL 可用于確定分配的位置:這在選擇使用 cudaMemcpyPeerAsync 制作 p2h2p 拷貝的上下文時很有用。 CU_POINTER_ATTRIBUTE_MEMPOOL_HANDLE 屬性是在 CUDA 11.3 中添加的,可用于調試和在執行 IPC 之前確認分配來自哪個池。

關于作者

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

審核編輯:郭婷

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

    關注

    28

    文章

    4949

    瀏覽量

    131272
  • CUDA
    +關注

    關注

    0

    文章

    123

    瀏覽量

    14131
收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關推薦
    熱點推薦

    九航星達KS-DVI0102型2通道DVI分配器使用手冊

    電子發燒友網站提供《九航星達KS-DVI0102型2通道DVI分配器使用手冊.doc》資料免費下載
    發表于 07-16 17:35 ?0次下載

    802-4-0.252,N型母頭功率分配器/合路器MECA

    802-4-0.252,N型母頭功率分配器/合路器MECA802-4-0.252是一款由MECA生產的N型母頭射頻功率分配器/合路器,802-4-0.252功率分配器/合路器平均額定功率為2瓦,頻率
    發表于 05-27 08:51

    MAX9174/MAX9175 670MHz、LVDS至LVDS和任意邏輯至LVDS 1:2分配器中文手冊

    MAX9174/MAX9175是670MHz低抖動、低扭曲的1:2分配器,尤其適合于保護切換、環回、時鐘和數據分配。這些器件具有1.0ps~(RMS)~ (最大)的超低隨機抖動,保證在那些定時誤差極為敏感的高速鏈路中可靠工作。
    的頭像 發表于 05-19 09:23 ?242次閱讀
    MAX9174/MAX9175 670MHz、LVDS至LVDS和任意邏輯至LVDS 1:2<b class='flag-5'>分配器</b>中文手冊

    PS2-88,PS2-88/NF功率分配器MCLI

    PS2-88,PS2-88/NF功率分配器MCLIPS2-88功率分配器是MCLI品牌推出的一款高性能射頻微波器件,屬于PS2系列2路功率分配器。PS2-88功率分配器是一款高性能的射
    發表于 03-20 09:31

    PS2-185/NF帶狀線2路電源分配器

    ,PS2-185/NF帶狀線2路電源分配器的插入損耗較低,通常在1.2dB左右,這意味著信號通過分配器時的衰減較小。隔離度:隔離度是指分配器各輸出端口之間的信號隔離程度。PS2-18
    發表于 01-08 09:23

    英邁質譜流路分配器:精準控制,引領質譜分析新高度

    質譜分析這一精密科學領域,流體的精準輸送對于獲取高質量數據至關重要。為了滿足這一嚴苛需求,Instrumax(英邁儀器)憑借其流體控制領域的深厚積累,推出了全新的質譜流路分配器。 這款質譜流路
    的頭像 發表于 12-26 14:14 ?465次閱讀

    HDMI分配器與轉換器的選擇與配置:連接多個設備或延長信號距離的必備工具

    HDMI分配器和轉換器是兩種常用的視頻信號管理設備,它們在家庭影院、會議室、監控系統等多種場合中發揮著重要作用。了解它們的特點和配置方法可以幫助用戶更好地選擇合適的設備,以滿足特定的視頻傳輸需求
    的頭像 發表于 09-26 10:12 ?945次閱讀

    CDCL1810A 1.8V、10 輸出高性能時鐘分配器數據表

    電子發燒友網站提供《CDCL1810A 1.8V、10 輸出高性能時鐘分配器數據表.pdf》資料免費下載
    發表于 08-23 10:08 ?0次下載
    CDCL1810A 1.8V、10 輸出高性能時鐘<b class='flag-5'>分配器</b>數據表

    CDCL6010 1.8V 11輸出時鐘乘法器、分配器、抖動消除器和緩沖器數據表

    電子發燒友網站提供《CDCL6010 1.8V 11輸出時鐘乘法器、分配器、抖動消除器和緩沖器數據表.pdf》資料免費下載
    發表于 08-22 11:18 ?0次下載
    CDCL6010 1.8V 11輸出時鐘乘法器、<b class='flag-5'>分配器</b>、抖動消除器和緩沖器數據表

    CDCL1810 1.8V 10路輸出高性能時鐘分配器數據表

    電子發燒友網站提供《CDCL1810 1.8V 10路輸出高性能時鐘分配器數據表.pdf》資料免費下載
    發表于 08-22 11:14 ?0次下載
    CDCL1810 1.8V 10路輸出高性能時鐘<b class='flag-5'>分配器</b>數據表

    CDCE18005高性能時鐘分配器數據表

    電子發燒友網站提供《CDCE18005高性能時鐘分配器數據表.pdf》資料免費下載
    發表于 08-21 11:12 ?0次下載
    CDCE18005高性能時鐘<b class='flag-5'>分配器</b>數據表

    CDCE62005高性能時鐘發生器和分配器數據表

    電子發燒友網站提供《CDCE62005高性能時鐘發生器和分配器數據表.pdf》資料免費下載
    發表于 08-21 11:12 ?0次下載
    CDCE62005高性能時鐘發生器和<b class='flag-5'>分配器</b>數據表

    LMK01000高性能時鐘緩沖器、分頻器和分配器數據表

    電子發燒友網站提供《LMK01000高性能時鐘緩沖器、分頻器和分配器數據表.pdf》資料免費下載
    發表于 08-21 09:53 ?0次下載
    LMK01000高性能時鐘緩沖器、分頻器和<b class='flag-5'>分配器</b>數據表

    CDCE72010十路輸出高性能時鐘同步器、抖動消除器和時鐘分配器數據表

    電子發燒友網站提供《CDCE72010十路輸出高性能時鐘同步器、抖動消除器和時鐘分配器數據表.pdf》資料免費下載
    發表于 08-21 09:26 ?0次下載
    CDCE72010十路輸出高性能時鐘同步器、抖動消除器和時鐘<b class='flag-5'>分配器</b>數據表

    功率合成和分配網絡有何特點

    為單一信號源的設備。射頻和微波系統中,功率合成器通常用于提高系統的輸出功率和效率。功率合成器的基本原理是將多個信號源的相位和幅度進行調整,使得它們合成點上相互疊加,從而實現功率的合并。 1.2 功率分配器 功率
    的頭像 發表于 08-13 14:37 ?1333次閱讀
    主站蜘蛛池模板: 天天综合久久 | 亚洲午夜一区二区三区 | 日韩a免费 | 末发育娇小性色xxxxx视频 | 狠狠丁香激情久久综合 | 国产美女一级高清免费观看 | 国产福利乳摇在线播放 | 成人欧美一区二区三区视频不卡 | 午夜一级毛片免费视频 | 欧美亚洲专区 | 视频在线观看一区二区三区 | а中文在线天堂 | 亚州1区2区3区4区产品乱码2021 | xyx性爽欧美视频 | 成人影院久久久久久影院 | 久久久久久久免费 | 人人爽影院 | 久久久久99精品成人片三人毛片 | 欧美极品另类 | 好硬好湿好爽再深一点h | 最近最新中文字幕在线第一页 | 狠狠色噜噜狠狠狠狠米奇777 | 天天干夜夜操视频 | 国产片无遮挡在线看床戏 | 国内免费视频成人精品 | 91九色在线视频 | 国产精品成人四虎免费视频 | 边做饭边被躁欧美三级小说 | yy6080亚洲半夜理论一级毛片 | 特黄特色大片免费视频大全 | 久久黄色网| 婷婷丁香社区 | 全亚洲最大的777io影院 | 欧美aaaav免费大片 | 天堂视频在线视频观看2018 | 男人午夜免费视频 | 扒开双腿猛进入jk校视频 | 日韩特级片 | 色综合久久久久久久久久久 | 欧美成人精品久久精品 | 丁香色婷婷 |