P4 to Git Change 1531829 by gandryey@gera-w8 on 2018/03/23 18:34:36
SWDEV-79445 - OCL generic changes and code clean-up - Implement ConstantBuffer management through a single managed buffer. It reduces the amount of allocated buffers on GPU Affected files ... ... //depot/stg/opencl/drivers/opencl/runtime/device/pal/palconstbuf.cpp#6 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/pal/palconstbuf.hpp#5 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/pal/palkernel.cpp#48 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/pal/palvirtual.cpp#79 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/pal/palvirtual.hpp#44 edit
This commit is contained in:
@@ -16,7 +16,6 @@ ManagedBuffer::ManagedBuffer(VirtualGPU& gpu, uint32_t size)
|
||||
, activeBuffer_(0)
|
||||
, size_(size)
|
||||
, wrtOffset_(0)
|
||||
, lastWrtSize_(0)
|
||||
, wrtAddress_(nullptr) {}
|
||||
|
||||
// ================================================================================================
|
||||
@@ -27,23 +26,10 @@ ManagedBuffer::~ManagedBuffer() {
|
||||
}
|
||||
delete it;
|
||||
}
|
||||
amd::AlignedMemory::deallocate(sysMemCopy_);
|
||||
}
|
||||
|
||||
// ================================================================================================
|
||||
bool ManagedBuffer::create(Resource::MemoryType type, bool constbuf) {
|
||||
if (constbuf) {
|
||||
// Create sysmem copy for the constant buffer.
|
||||
// Allocate extra memory to account the internal arguments
|
||||
sysMemCopy_ = reinterpret_cast<address>(amd::AlignedMemory::allocate(
|
||||
2 * gpu_.dev().info().maxParameterSize_, 256));
|
||||
if (sysMemCopy_ == nullptr) {
|
||||
LogPrintfError("We couldn't allocate sysmem copy for constant buffer, size(%d)!", size_);
|
||||
return false;
|
||||
}
|
||||
memset(sysMemCopy_, 0, gpu_.dev().info().maxParameterSize_);
|
||||
}
|
||||
|
||||
bool ManagedBuffer::create(Resource::MemoryType type) {
|
||||
for (uint i = 0; i < buffers_.size(); ++i) {
|
||||
buffers_[i] = new Memory(const_cast<pal::Device&>(gpu_.dev()), size_);
|
||||
if (nullptr == buffers_[i] || !buffers_[i]->create(type)) {
|
||||
@@ -66,14 +52,13 @@ bool ManagedBuffer::create(Resource::MemoryType type, bool constbuf) {
|
||||
}
|
||||
|
||||
// ================================================================================================
|
||||
bool ManagedBuffer::uploadDataToHw(uint32_t size) {
|
||||
static constexpr uint32_t HwCbAlignment = 256;
|
||||
address ManagedBuffer::reserve(uint32_t size, uint64_t* gpu_address) {
|
||||
static constexpr uint32_t MemAlignment = 256;
|
||||
|
||||
// Align copy size on the vector's boundary
|
||||
uint32_t count = amd::alignUp(size, 16);
|
||||
wrtOffset_ += lastWrtSize_;
|
||||
// Align reserve size on the vector's boundary
|
||||
uint32_t count = amd::alignUp(size, MemAlignment);
|
||||
|
||||
// Check if CB has enough space for copy
|
||||
// Check if buffer has enough space for reservation
|
||||
if ((wrtOffset_ + count) > size_) {
|
||||
// Get the next buffer in the list
|
||||
++activeBuffer_;
|
||||
@@ -82,15 +67,49 @@ bool ManagedBuffer::uploadDataToHw(uint32_t size) {
|
||||
buffers_[activeBuffer_]->wait(gpu_);
|
||||
wrtAddress_ = buffers_[activeBuffer_]->data();
|
||||
wrtOffset_ = 0;
|
||||
lastWrtSize_ = 0;
|
||||
}
|
||||
|
||||
// Update memory with new CB data
|
||||
memcpy((reinterpret_cast<char*>(wrtAddress_) + wrtOffset_), sysMemCopy_, count);
|
||||
*gpu_address = buffers_[activeBuffer_]->vmAddress() + wrtOffset_;
|
||||
address cpu_address = wrtAddress_ + wrtOffset_;
|
||||
|
||||
// Adjust the offset by the reserved size
|
||||
wrtOffset_ += count;
|
||||
|
||||
// Adjust the size by the HW CB buffer alignment
|
||||
lastWrtSize_ = amd::alignUp(size, HwCbAlignment);
|
||||
return cpu_address;
|
||||
}
|
||||
|
||||
// ================================================================================================
|
||||
ConstantBuffer::ConstantBuffer(ManagedBuffer& mbuf, uint32_t size)
|
||||
: mbuf_(mbuf)
|
||||
, sys_mem_copy_(nullptr)
|
||||
, size_(size)
|
||||
{}
|
||||
|
||||
// ================================================================================================
|
||||
ConstantBuffer::~ConstantBuffer() {
|
||||
amd::AlignedMemory::deallocate(sys_mem_copy_);
|
||||
}
|
||||
|
||||
// ================================================================================================
|
||||
bool ConstantBuffer::Create() {
|
||||
// Create sysmem copy for the constant buffer.
|
||||
sys_mem_copy_ = reinterpret_cast<address>(amd::AlignedMemory::allocate(size_, 256));
|
||||
if (sys_mem_copy_ == nullptr) {
|
||||
LogPrintfError("We couldn't allocate sysmem copy for constant buffer, size(%d)!", size_);
|
||||
return false;
|
||||
}
|
||||
memset(sys_mem_copy_, 0, size_);
|
||||
return true;
|
||||
}
|
||||
|
||||
// ================================================================================================
|
||||
uint64_t ConstantBuffer::UploadDataToHw(uint32_t size) const
|
||||
{
|
||||
uint64_t vm_address;
|
||||
address cpu_address = mbuf_.reserve(size, &vm_address);
|
||||
// Update memory with new CB data
|
||||
memcpy(cpu_address, sys_mem_copy_, size);
|
||||
return vm_address;
|
||||
}
|
||||
|
||||
} // namespace pal
|
||||
|
||||
@@ -20,27 +20,22 @@ class ManagedBuffer : public amd::HeapObject {
|
||||
~ManagedBuffer();
|
||||
|
||||
//! Creates the real HW constant buffer
|
||||
bool create(Resource::MemoryType type, bool constBuf = false);
|
||||
bool create(Resource::MemoryType type);
|
||||
|
||||
/*! \brief Uploads current constant buffer data from sysMemCopy_ to HW
|
||||
*
|
||||
* \return True if the data upload was succesful
|
||||
*/
|
||||
bool uploadDataToHw(uint32_t size //!< real data size for upload
|
||||
);
|
||||
|
||||
//! Returns a pointer to the system memory copy for CB
|
||||
address sysMemCopy() const { return sysMemCopy_; }
|
||||
address reserve(uint32_t size, //!< real data size for upload
|
||||
uint64_t* gpu_address);
|
||||
|
||||
//! Returns CB size
|
||||
uint32_t size() const { return size_; }
|
||||
|
||||
//! Returns current write offset for the constant buffer
|
||||
//! Returns current write offset for the managed buffer
|
||||
uint32_t wrtOffset() const { return wrtOffset_; }
|
||||
|
||||
//! Returns last write size for the constant buffer
|
||||
uint32_t lastWrtSize() const { return lastWrtSize_; }
|
||||
|
||||
//! Returns active GPU buffer
|
||||
Memory* activeMemory() const { return buffers_[activeBuffer_]; }
|
||||
|
||||
uint64_t vmAddress() const { return buffers_[activeBuffer_]->vmAddress(); }
|
||||
@@ -58,11 +53,48 @@ class ManagedBuffer : public amd::HeapObject {
|
||||
VirtualGPU& gpu_; //!< Virtual GPU object
|
||||
std::vector<Memory*> buffers_; //!< Buffers for management
|
||||
uint32_t activeBuffer_; //!< Current active buffer
|
||||
address sysMemCopy_; //!< System memory copy
|
||||
uint32_t size_; //!< Constant buffer size
|
||||
uint32_t wrtOffset_; //!< Current write offset
|
||||
uint32_t lastWrtSize_; //!< Last write size
|
||||
void* wrtAddress_; //!< Write address in CB
|
||||
address wrtAddress_; //!< Write address in CB
|
||||
};
|
||||
|
||||
//! Constant buffer
|
||||
class ConstantBuffer : public amd::HeapObject {
|
||||
public:
|
||||
//! Constructor for the ConstBuffer class
|
||||
ConstantBuffer(ManagedBuffer& mbuf, //!< Managed buffer
|
||||
uint32_t size
|
||||
);
|
||||
|
||||
//! Destructor for the ConstBuffer class
|
||||
~ConstantBuffer();
|
||||
|
||||
//! Creates the real HW constant buffer
|
||||
bool Create();
|
||||
|
||||
/*! \brief Uploads current constant buffer data from sysMemCopy_ to HW
|
||||
*
|
||||
* \return GPU address for the uploaded data
|
||||
*/
|
||||
uint64_t UploadDataToHw(uint32_t size //!< real data size for upload
|
||||
) const;
|
||||
|
||||
//! Returns a pointer to the system memory copy for CB
|
||||
address SysMemCopy(uint32_t size = 0) const { return sys_mem_copy_; }
|
||||
|
||||
//! Returns active GPU buffer
|
||||
Memory* ActiveMemory() const { return mbuf_.activeMemory(); }
|
||||
|
||||
private:
|
||||
//! Disable copy constructor
|
||||
ConstantBuffer(const ConstantBuffer&) = delete;
|
||||
|
||||
//! Disable operator=
|
||||
ConstantBuffer& operator=(const ConstantBuffer&) = delete;
|
||||
|
||||
ManagedBuffer& mbuf_; //!< Managed buffer on GPU
|
||||
address sys_mem_copy_; //!< System memory copy
|
||||
uint32_t size_; //!< Constant buffer size
|
||||
};
|
||||
|
||||
/*@}*/} // namespace pal
|
||||
|
||||
@@ -920,8 +920,8 @@ hsa_kernel_dispatch_packet_t* HSAILKernel::loadArguments(
|
||||
const_address parameters, bool nativeMem, uint64_t vmDefQueue, uint64_t* vmParentWrap) const {
|
||||
static const bool WaitOnBusyEngine = true;
|
||||
uint64_t ldsAddress = ldsSize();
|
||||
address aqlArgBuf = gpu.cb(0)->sysMemCopy();
|
||||
address aqlStruct = gpu.cb(1)->sysMemCopy();
|
||||
address aqlArgBuf = gpu.cb(0)->SysMemCopy();
|
||||
address aqlStruct = gpu.cb(1)->SysMemCopy();
|
||||
bool srdResource = false;
|
||||
|
||||
if (dynamicParallelism()) {
|
||||
@@ -929,10 +929,9 @@ hsa_kernel_dispatch_packet_t* HSAILKernel::loadArguments(
|
||||
AmdAqlWrap* wrap = reinterpret_cast<AmdAqlWrap*>(aqlStruct);
|
||||
memset(wrap, 0, sizeof(AmdAqlWrap));
|
||||
wrap->state = AQL_WRAP_BUSY;
|
||||
ManagedBuffer* cb = gpu.constBufs_[1];
|
||||
cb->uploadDataToHw(sizeof(AmdAqlWrap));
|
||||
*vmParentWrap = cb->vmAddress() + cb->wrtOffset();
|
||||
gpu.addVmMemory(cb->activeMemory());
|
||||
const ConstantBuffer* cb = gpu.cb(1);
|
||||
*vmParentWrap = cb->UploadDataToHw(sizeof(AmdAqlWrap));
|
||||
gpu.addVmMemory(cb->ActiveMemory());
|
||||
}
|
||||
|
||||
const amd::KernelSignature& signature = kernel.signature();
|
||||
@@ -1066,12 +1065,11 @@ hsa_kernel_dispatch_packet_t* HSAILKernel::loadArguments(
|
||||
case HSAIL_ARGTYPE_REFERENCE: {
|
||||
// Copy the current structure into CB1
|
||||
memcpy(aqlStruct, paramaddr, arg->size_);
|
||||
ManagedBuffer* cb = gpu.constBufs_[1];
|
||||
cb->uploadDataToHw(arg->size_);
|
||||
const ConstantBuffer* cb = gpu.cb(1);
|
||||
// Then use a pointer in aqlArgBuffer to CB1
|
||||
size_t gpuPtr = static_cast<size_t>(cb->vmAddress() + cb->wrtOffset());
|
||||
size_t gpuPtr = static_cast<size_t>(cb->UploadDataToHw(arg->size_));
|
||||
WriteAqlArg(&aqlArgBuf, &gpuPtr, sizeof(size_t), sizeof(size_t));
|
||||
gpu.addVmMemory(cb->activeMemory());
|
||||
gpu.addVmMemory(cb->ActiveMemory());
|
||||
break;
|
||||
}
|
||||
case HSAIL_ARGTYPE_VALUE:
|
||||
@@ -1109,12 +1107,11 @@ hsa_kernel_dispatch_packet_t* HSAILKernel::loadArguments(
|
||||
if (image->memoryType() == Resource::ImageView) {
|
||||
// Copy the current structre into CB1
|
||||
memcpy(aqlStruct, image->hwState(), HsaImageObjectSize);
|
||||
ManagedBuffer* cb = gpu.constBufs_[1];
|
||||
cb->uploadDataToHw(HsaImageObjectSize);
|
||||
const ConstantBuffer* cb = gpu.cb(1);
|
||||
// Then use a pointer in aqlArgBuffer to CB1
|
||||
uint64_t srd = cb->vmAddress() + cb->wrtOffset();
|
||||
uint64_t srd = cb->UploadDataToHw(HsaImageObjectSize);
|
||||
WriteAqlArg(&aqlArgBuf, &srd, sizeof(srd), sizeof(srd));
|
||||
gpu.addVmMemory(cb->activeMemory());
|
||||
gpu.addVmMemory(cb->ActiveMemory());
|
||||
} else {
|
||||
uint64_t srd = image->hwSrd();
|
||||
WriteAqlArg(&aqlArgBuf, &srd, sizeof(srd), sizeof(srd));
|
||||
@@ -1171,15 +1168,15 @@ hsa_kernel_dispatch_packet_t* HSAILKernel::loadArguments(
|
||||
#if defined(WITH_LIGHTNING_COMPILER)
|
||||
// Check there is no arguments' buffer overflow. We may not use all the
|
||||
// hidden argument slots.
|
||||
assert(aqlArgBuf <= (gpu.cb(0)->sysMemCopy() + argsBufferSize()));
|
||||
assert(aqlArgBuf <= (gpu.cb(0)->SysMemCopy() + argsBufferSize()));
|
||||
#else // !defined(WITH_LIGHTNING_COMPILER)
|
||||
// HSAIL kernarg segment size is rounded up to multiple of 16.
|
||||
aqlArgBuf = amd::alignUp(aqlArgBuf, 16);
|
||||
assert((aqlArgBuf == (gpu.cb(0)->sysMemCopy() + argsBufferSize())) &&
|
||||
assert((aqlArgBuf == (gpu.cb(0)->SysMemCopy() + argsBufferSize())) &&
|
||||
"Size and the number of arguments don't match!");
|
||||
#endif // !defined(WITH_LIGHTNING_COMPILER)
|
||||
hsa_kernel_dispatch_packet_t* hsaDisp =
|
||||
reinterpret_cast<hsa_kernel_dispatch_packet_t*>(gpu.cb(0)->sysMemCopy() + argsBufferSize());
|
||||
reinterpret_cast<hsa_kernel_dispatch_packet_t*>(gpu.cb(0)->SysMemCopy() + argsBufferSize());
|
||||
|
||||
amd::NDRange local(sizes.local());
|
||||
const amd::NDRange& global = sizes.global();
|
||||
@@ -1204,15 +1201,15 @@ hsa_kernel_dispatch_packet_t* HSAILKernel::loadArguments(
|
||||
hsaDisp->group_segment_size = ldsAddress - ldsSize();
|
||||
hsaDisp->kernel_object = gpuAqlCode();
|
||||
|
||||
ManagedBuffer* cb = gpu.constBufs_[0];
|
||||
cb->uploadDataToHw(argsBufferSize() + sizeof(hsa_kernel_dispatch_packet_t));
|
||||
uint64_t argList = cb->vmAddress() + cb->wrtOffset();
|
||||
const ConstantBuffer* cb = gpu.cb(0);
|
||||
uint64_t argList = cb->UploadDataToHw(
|
||||
argsBufferSize() + sizeof(hsa_kernel_dispatch_packet_t));
|
||||
|
||||
hsaDisp->kernarg_address = reinterpret_cast<void*>(argList);
|
||||
hsaDisp->reserved2 = 0;
|
||||
hsaDisp->completion_signal.handle = 0;
|
||||
|
||||
gpu.addVmMemory(cb->activeMemory());
|
||||
gpu.addVmMemory(cb->ActiveMemory());
|
||||
gpu.addVmMemory(&prog().codeSegGpu());
|
||||
for (pal::Memory* mem : prog().globalStores()) {
|
||||
gpu.addVmMemory(mem);
|
||||
|
||||
@@ -702,6 +702,7 @@ VirtualGPU::VirtualGPU(Device& device)
|
||||
printfDbgHSA_(nullptr),
|
||||
tsCache_(nullptr),
|
||||
dmaFlushMgmt_(device),
|
||||
writeBuffer_(nullptr),
|
||||
hwRing_(0),
|
||||
readjustTimeGPU_(0),
|
||||
lastTS_(nullptr),
|
||||
@@ -812,6 +813,13 @@ bool VirtualGPU::create(bool profiling, uint deviceQueueSize, uint rtCUs,
|
||||
Unimplemented();
|
||||
}
|
||||
|
||||
writeBuffer_ = new ManagedBuffer(*this, dev().settings().stagedXferSize_);
|
||||
if ((writeBuffer_ == nullptr) || !writeBuffer_->create(Resource::RemoteUSWC)) {
|
||||
// We failed to create a constant buffer
|
||||
delete writeBuffer_;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Diable double copy optimization,
|
||||
// since UAV read from nonlocal is fast enough
|
||||
blitSetup.disableCopyBufferToImageOpt_ = true;
|
||||
@@ -934,6 +942,8 @@ VirtualGPU::~VirtualGPU() {
|
||||
delete constBufs_[i];
|
||||
}
|
||||
|
||||
delete writeBuffer_;
|
||||
|
||||
//! @todo Temporarily keep the buffer mapped for debug purpose
|
||||
if (nullptr != schedParams_) {
|
||||
schedParams_->unmap(this);
|
||||
@@ -2803,15 +2813,16 @@ void VirtualGPU::waitEventLock(CommandBatch* cb) {
|
||||
}
|
||||
|
||||
bool VirtualGPU::allocConstantBuffers() {
|
||||
// Allocate constant buffers, GCN doesn't really have a limit
|
||||
static constexpr uint32_t MinCbSize = 256 * Ki;
|
||||
// Allocate constant buffers.
|
||||
// Use double size, reported to the app to account for internal arguments
|
||||
const uint32_t MinCbSize = 2 * dev().info().maxParameterSize_;
|
||||
uint i;
|
||||
|
||||
// Create/reallocate constant buffer resources
|
||||
for (i = 0; i < MaxConstBuffersArguments; ++i) {
|
||||
ManagedBuffer* constBuf = new ManagedBuffer(*this, MinCbSize);
|
||||
ConstantBuffer* constBuf = new ConstantBuffer(*writeBuffer_, MinCbSize);
|
||||
|
||||
if ((constBuf != nullptr) && constBuf->create(Resource::RemoteUSWC, true)) {
|
||||
if ((constBuf != nullptr) && constBuf->Create()) {
|
||||
addConstBuffer(constBuf);
|
||||
} else {
|
||||
// We failed to create a constant buffer
|
||||
|
||||
@@ -207,7 +207,7 @@ class VirtualGPU : public device::VirtualDevice {
|
||||
State() : value_(0) {}
|
||||
};
|
||||
|
||||
typedef std::vector<ManagedBuffer*> constbufs_t;
|
||||
typedef std::vector<ConstantBuffer*> constbufs_t;
|
||||
|
||||
class MemoryDependency : public amd::EmbeddedObject {
|
||||
public:
|
||||
@@ -341,12 +341,10 @@ class VirtualGPU : public device::VirtualDevice {
|
||||
);
|
||||
|
||||
//! Returns a resource associated with the constant buffer
|
||||
const ManagedBuffer* cb(uint idx) const { return constBufs_[idx]; }
|
||||
const ConstantBuffer* cb(uint idx) const { return constBufs_[idx]; }
|
||||
|
||||
//! Adds CAL objects into the constant buffer vector
|
||||
void addConstBuffer(ManagedBuffer* cb) { constBufs_.push_back(cb); }
|
||||
|
||||
constbufs_t constBufs_; //!< constant buffers
|
||||
void addConstBuffer(ConstantBuffer* cb) { constBufs_.push_back(cb); }
|
||||
|
||||
//! Start the command profiling
|
||||
void profilingBegin(amd::Command& command, //!< Command queue object
|
||||
@@ -597,6 +595,9 @@ class VirtualGPU : public device::VirtualDevice {
|
||||
std::vector<Memory*> xferWriteBuffers_; //!< Stage write buffers
|
||||
std::vector<amd::Memory*> pinnedMems_; //!< Pinned memory list
|
||||
|
||||
ManagedBuffer* writeBuffer_; //!< Managed write buffer
|
||||
constbufs_t constBufs_; //!< constant buffers
|
||||
|
||||
typedef std::queue<CommandBatch*> CommandBatchQueue;
|
||||
CommandBatchQueue cbQueue_; //!< Queue of command batches
|
||||
CommandBatchQueue freeCbQueue_; //!< Queue of free command batches
|
||||
|
||||
Reference in New Issue
Block a user