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
Этот коммит содержится в:
foreman
2014-11-14 14:07:55 -05:00
родитель 0fc8ceaa73
Коммит dc8a3205ce
4 изменённых файлов: 64 добавлений и 90 удалений
+30 -70
Просмотреть файл
@@ -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, &params)) {
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, &params)) {
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);
+8 -8
Просмотреть файл
@@ -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
+23 -12
Просмотреть файл
@@ -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);
}
}
}
+3
Просмотреть файл
@@ -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_; }