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_; }