From dc8a3205ce7483fe7676f390089d55364e82cf80 Mon Sep 17 00:00:00 2001
From: foreman
Date: Fri, 14 Nov 2014 14:07:55 -0500
Subject: [PATCH] P4 to Git Change 1097200 by gandryey@gera-dev-w7 on
2014/11/14 13:59:46
ECR #304775 - Optimize oclBandwidthTest from nVidia SDK
- Cache pinned memory, since the benchmark sends the same transfer in a single batch. Thus we could avoid pin/unpin
- Swap SDMA engine allocation order. Blit manager allocates a queue on device, thus the first app queue was getting the paging second SDMA.
Affected files ...
... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpublit.cpp#112 edit
... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpublit.hpp#37 edit
... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpuvirtual.cpp#339 edit
... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpuvirtual.hpp#121 edit
---
rocclr/runtime/device/gpu/gpublit.cpp | 100 +++++++----------------
rocclr/runtime/device/gpu/gpublit.hpp | 16 ++--
rocclr/runtime/device/gpu/gpuvirtual.cpp | 35 +++++---
rocclr/runtime/device/gpu/gpuvirtual.hpp | 3 +
4 files changed, 64 insertions(+), 90 deletions(-)
diff --git a/rocclr/runtime/device/gpu/gpublit.cpp b/rocclr/runtime/device/gpu/gpublit.cpp
index 65bbff4ec4..a0411a33f8 100644
--- a/rocclr/runtime/device/gpu/gpublit.cpp
+++ b/rocclr/runtime/device/gpu/gpublit.cpp
@@ -15,6 +15,7 @@ DmaBlitManager::DmaBlitManager(VirtualGPU& gpu, Setup setup)
: HostBlitManager(gpu, setup)
, MinSizeForPinnedTransfer(dev().settings().pinnedMinXferSize_)
, completeOperation_(false)
+ , context_(NULL)
{
}
@@ -143,9 +144,7 @@ DmaBlitManager::readBuffer(
// Find the partial size for unaligned copy
size_t partial = reinterpret_cast(dstHost) - tmpHost;
- Resource* pin[MaxPinnedBuffers];
- memset(pin, 0, sizeof(Resource*) * MaxPinnedBuffers);
- uint pinIdx = 0;
+ amd::Memory* pinned = NULL;
bool first = true;
size_t tmpSize;
size_t pinAllocSize;
@@ -167,35 +166,23 @@ DmaBlitManager::readBuffer(
}
amd::Coord3D dst(partial, 0, 0);
amd::Coord3D srcPin(origin[0] + offset, 0, 0);
- amd::HostMemoryReference hostMem(tmpHost);
amd::Coord3D copySizePin(tmpSize, 0, 0);
+ size_t partial2;
// Allocate a GPU resource for pinning
- pin[pinIdx] = new Resource(
- dev(), pinAllocSize / Heap::ElementSize, Heap::ElementType);
+ pinned = pinHostMemory(tmpHost, pinAllocSize, partial2);
- if (pin[pinIdx] != NULL) {
- Resource::PinnedParams params;
- params.owner_ = NULL;
- params.gpu_ = &gpu();
- params.hostMemRef_ = &hostMem;
- params.size_ = pinAllocSize;
+ if (pinned != NULL) {
+ // Get device memory for this virtual device
+ Memory* dstMemory = dev().getGpuMemory(pinned);
- // Create memory object
- if (pin[pinIdx]->create(Resource::Pinned, ¶ms)) {
- if (!gpuMem(srcMemory).partialMemCopyTo(
- gpu(), srcPin, dst, copySizePin, *pin[pinIdx])) {
- LogWarning("DmaBlitManager::readBuffer failed a pinned copy!");
- break;
- }
- }
- else {
- LogWarning("DmaBlitManager::readBuffer failed to pin a resource!");
+ if (!gpuMem(srcMemory).partialMemCopyTo(
+ gpu(), srcPin, dst, copySizePin, *dstMemory)) {
+ LogWarning("DmaBlitManager::readBuffer failed a pinned copy!");
+ gpu().addPinnedMem(pinned);
break;
}
- pinIdx = (pinIdx + 1) % MaxPinnedBuffers;
- delete pin[pinIdx];
- pin[pinIdx] = NULL;
+ gpu().addPinnedMem(pinned);
}
else {
LogWarning("DmaBlitManager::readBuffer failed to pin a resource!");
@@ -205,10 +192,6 @@ DmaBlitManager::readBuffer(
offset += tmpSize;
tmpHost = reinterpret_cast(tmpHost) + tmpSize + partial;
}
-
- for (uint idx = 0; idx < MaxPinnedBuffers; ++idx) {
- delete pin[idx];
- }
}
if (0 != srcSize) {
@@ -398,9 +381,7 @@ DmaBlitManager::writeBuffer(
// Find the partial size for unaligned copy
size_t partial = reinterpret_cast(srcHost) - tmpHost;
- Resource* pin[MaxPinnedBuffers];
- memset(pin, 0, sizeof(Resource*) * MaxPinnedBuffers);
- uint pinIdx = 0;
+ amd::Memory* pinned = NULL;
bool first = true;
size_t tmpSize;
size_t pinAllocSize;
@@ -422,35 +403,23 @@ DmaBlitManager::writeBuffer(
}
amd::Coord3D src(partial, 0, 0);
amd::Coord3D dstPin(origin[0] + offset, 0, 0);
- amd::HostMemoryReference hostMem(tmpHost);
amd::Coord3D copySizePin(tmpSize, 0, 0);
+ size_t partial2;
// Allocate a GPU resource for pinning
- pin[pinIdx] = new Resource(
- dev(), pinAllocSize / Heap::ElementSize, Heap::ElementType);
+ pinned = pinHostMemory(tmpHost, pinAllocSize, partial2);
- if (pin[pinIdx] != NULL) {
- Resource::PinnedParams params;
- params.owner_ = NULL;
- params.gpu_ = &gpu();
- params.hostMemRef_ = &hostMem;
- params.size_ = pinAllocSize;
+ if (pinned != NULL) {
+ // Get device memory for this virtual device
+ Memory* srcMemory = dev().getGpuMemory(pinned);
- // Create memory object
- if (pin[pinIdx]->create(Resource::Pinned, ¶ms)) {
- if (!pin[pinIdx]->partialMemCopyTo(
- gpu(), src, dstPin, copySizePin, gpuMem(dstMemory))) {
- LogWarning("DmaBlitManager::writeBuffer failed a pinned copy!");
- break;
- }
- }
- else {
- LogWarning("DmaBlitManager::writeBuffer failed to pin a resource!");
+ if (!srcMemory->partialMemCopyTo(
+ gpu(), src, dstPin, copySizePin, gpuMem(dstMemory))) {
+ LogWarning("DmaBlitManager::writeBuffer failed a pinned copy!");
+ gpu().addPinnedMem(pinned);
break;
}
- pinIdx = (pinIdx + 1) % MaxPinnedBuffers;
- delete pin[pinIdx];
- pin[pinIdx] = NULL;
+ gpu().addPinnedMem(pinned);
}
else {
LogWarning("DmaBlitManager::writeBuffer failed to pin a resource!");
@@ -460,10 +429,6 @@ DmaBlitManager::writeBuffer(
offset += tmpSize;
tmpHost = reinterpret_cast(tmpHost) + tmpSize + partial;
}
-
- for (uint idx = 0; idx < MaxPinnedBuffers; ++idx) {
- delete pin[idx];
- }
}
if (dstSize != 0) {
@@ -774,7 +739,6 @@ KernelBlitManager::KernelBlitManager(
VirtualGPU& gpu, Setup setup)
: DmaBlitManager(gpu, setup)
, program_(NULL)
- , context_(NULL)
, constantBuffer_(NULL)
, xferBufferSize_(0)
, lockXferOps_(NULL)
@@ -2202,11 +2166,6 @@ KernelBlitManager::readBuffer(
gpu().addPinnedMem(amdMemory);
}
else {
- // Check if runtime has to pin a big allocation and
- // release all pinned memory
- if (pinSize > dev().settings().pinnedXferSize_) {
- gpu().releasePinnedMem();
- }
result = DmaBlitManager::readBuffer(
srcMemory, dstHost, origin, size, entire);
}
@@ -2324,11 +2283,6 @@ KernelBlitManager::writeBuffer(
gpu().addPinnedMem(amdMemory);
}
else {
- // Check if runtime has to pin a big allocation and
- // release all pinned memory
- if (pinSize > dev().settings().pinnedXferSize_) {
- gpu().releasePinnedMem();
- }
result = DmaBlitManager::writeBuffer(
srcHost, dstMemory, origin, size, entire);
}
@@ -2804,7 +2758,7 @@ KernelBlitManager::runScheduler(
}
amd::Memory*
-KernelBlitManager::pinHostMemory(
+DmaBlitManager::pinHostMemory(
const void* hostMem,
size_t pinSize,
size_t& partial) const
@@ -2824,6 +2778,12 @@ KernelBlitManager::pinHostMemory(
// Recalculate pin memory size
pinAllocSize = amd::alignUp(pinSize + partial, PinnedMemoryAlignment);
+ amdMemory = gpu().findPinnedMem(tmpHost, pinAllocSize);
+
+ if (NULL != amdMemory) {
+ return amdMemory;
+ }
+
amdMemory = new(*context_)
amd::Buffer(*context_, CL_MEM_USE_HOST_PTR, pinAllocSize);
diff --git a/rocclr/runtime/device/gpu/gpublit.hpp b/rocclr/runtime/device/gpu/gpublit.hpp
index 93d4ee7b46..5b3fb86d13 100644
--- a/rocclr/runtime/device/gpu/gpublit.hpp
+++ b/rocclr/runtime/device/gpu/gpublit.hpp
@@ -168,8 +168,16 @@ protected:
inline Memory& gpuMem(device::Memory& mem) const;
+ //! Pins host memory for GPU access
+ amd::Memory* pinHostMemory(
+ const void* hostMem, //!< Host memory pointer
+ size_t pinSize, //!< Host memory size
+ size_t& partial //!< Extra offset for memory alignment
+ ) const;
+
const size_t MinSizeForPinnedTransfer;
bool completeOperation_; //!< DMA blit manager must complete operation
+ amd::Context* context_; //!< A dummy context
private:
@@ -406,13 +414,6 @@ private:
Device& device //!< Device object
);
- //! Pins host memory for GPU access
- amd::Memory* pinHostMemory(
- const void* hostMem, //!< Host memory pointer
- size_t pinSize, //!< Host memory size
- size_t& partial //!< Extra offset for memory alignment
- ) const;
-
//! Creates a view memory object
Memory* createView(
const Memory& parent, //!< Parent memory object
@@ -427,7 +428,6 @@ private:
amd::Program* program_; //!< GPU program obejct
amd::Kernel* kernels_[BlitTotal]; //!< GPU kernels for blit
- amd::Context* context_; //!< A dummy context
amd::Memory* constantBuffer_; //!< An internal CB for blits
amd::Memory* xferBuffers_[MaxXferBuffers]; //!< Transfer buffers for images
size_t xferBufferSize_; //!< Transfer buffer size
diff --git a/rocclr/runtime/device/gpu/gpuvirtual.cpp b/rocclr/runtime/device/gpu/gpuvirtual.cpp
index fb2d38f007..b693322eec 100644
--- a/rocclr/runtime/device/gpu/gpuvirtual.cpp
+++ b/rocclr/runtime/device/gpu/gpuvirtual.cpp
@@ -229,9 +229,8 @@ VirtualGPU::addXferWrite(Resource& resource)
void
VirtualGPU::releaseXferWrite()
{
- for (std::list::iterator it = xferWriteBuffers_.begin();
- it != xferWriteBuffers_.end(); ++it) {
- dev().xferWrite().release(*this, *(*it));
+ for (auto& resource : xferWriteBuffers_) {
+ dev().xferWrite().release(*this, *resource);
}
xferWriteBuffers_.clear();
}
@@ -244,23 +243,35 @@ VirtualGPU::addPinnedMem(amd::Memory* mem)
pinnedMems_.pop_front();
}
- // Start operation, since we should release mem object
- flushDMA(getGpuEvent(dev().getGpuMemory(mem))->engineId_);
+ if (NULL == findPinnedMem(mem->getHostMem(), mem->getSize())) {
+ // Start operation, since we should release mem object
+ flushDMA(getGpuEvent(dev().getGpuMemory(mem))->engineId_);
- // Delay destruction
- pinnedMems_.push_back(mem);
+ // Delay destruction
+ pinnedMems_.push_back(mem);
+ }
}
void
VirtualGPU::releasePinnedMem()
{
- for (std::list::iterator it = pinnedMems_.begin();
- it != pinnedMems_.end(); ++it) {
- (*it)->release();
+ for (auto& amdMemory : pinnedMems_) {
+ amdMemory->release();
}
pinnedMems_.clear();
}
+amd::Memory*
+VirtualGPU::findPinnedMem(void* addr, size_t size)
+{
+ for (auto& amdMemory : pinnedMems_) {
+ if ((amdMemory->getHostMem() == addr) && (size <= amdMemory->getSize())) {
+ return amdMemory;
+ }
+ }
+ return NULL;
+}
+
bool
VirtualGPU::createVirtualQueue(uint deviceQueueSize)
{
@@ -486,10 +497,10 @@ VirtualGPU::create(
engineMask = dev().engines().getMask((gslEngineID)(GSL_ENGINEID_COMPUTE0 + idx));
if (dev().canDMA()) {
if (idx & 0x1) {
- engineMask |= dev().engines().getMask(GSL_ENGINEID_DRMDMA1);
+ engineMask |= dev().engines().getMask(GSL_ENGINEID_DRMDMA0);
}
else {
- engineMask |= dev().engines().getMask(GSL_ENGINEID_DRMDMA0);
+ engineMask |= dev().engines().getMask(GSL_ENGINEID_DRMDMA1);
}
}
}
diff --git a/rocclr/runtime/device/gpu/gpuvirtual.hpp b/rocclr/runtime/device/gpu/gpuvirtual.hpp
index 79e070bb33..daa6433e0e 100644
--- a/rocclr/runtime/device/gpu/gpuvirtual.hpp
+++ b/rocclr/runtime/device/gpu/gpuvirtual.hpp
@@ -342,6 +342,9 @@ public:
//! Release pinned memory objects
void releasePinnedMem();
+ //! Finds if pinned memory is cached
+ amd::Memory* findPinnedMem(void* addr, size_t size);
+
//! Returns gsl memory object for VM
const gslMemObject* vmMems() const { return vmMems_; }