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
Этот коммит содержится в:
@@ -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<const char*>(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<char*>(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<const char*>(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<char*>(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);
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -229,9 +229,8 @@ VirtualGPU::addXferWrite(Resource& resource)
|
||||
void
|
||||
VirtualGPU::releaseXferWrite()
|
||||
{
|
||||
for (std::list<Resource*>::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<amd::Memory*>::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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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_; }
|
||||
|
||||
|
||||
Ссылка в новой задаче
Block a user