diff --git a/rocclr/runtime/device/gpu/gpudevice.hpp b/rocclr/runtime/device/gpu/gpudevice.hpp index 985eb079f6..3195289f75 100644 --- a/rocclr/runtime/device/gpu/gpudevice.hpp +++ b/rocclr/runtime/device/gpu/gpudevice.hpp @@ -478,7 +478,7 @@ public: typedef std::vector VirtualGPUs; //! Returns the list of all virtual GPUs running on this device - const VirtualGPUs vgpus() const { return vgpus_; } + const VirtualGPUs& vgpus() const { return vgpus_; } VirtualGPUs vgpus_; //!< The list of all running virtual gpus (lock protected) //! Scratch buffer allocation diff --git a/rocclr/runtime/device/pal/paldevice.hpp b/rocclr/runtime/device/pal/paldevice.hpp index 6bbd1bc50d..f689ea0646 100644 --- a/rocclr/runtime/device/pal/paldevice.hpp +++ b/rocclr/runtime/device/pal/paldevice.hpp @@ -386,7 +386,7 @@ public: typedef std::vector VirtualGPUs; //! Returns the list of all virtual GPUs running on this device - const VirtualGPUs vgpus() const { return vgpus_; } + const VirtualGPUs& vgpus() const { return vgpus_; } VirtualGPUs vgpus_; //!< The list of all running virtual gpus (lock protected) //! Scratch buffer allocation diff --git a/rocclr/runtime/device/pal/palvirtual.cpp b/rocclr/runtime/device/pal/palvirtual.cpp index b88737cb81..b81f4db604 100644 --- a/rocclr/runtime/device/pal/palvirtual.cpp +++ b/rocclr/runtime/device/pal/palvirtual.cpp @@ -170,7 +170,7 @@ VirtualGPU::Queue::submit(bool forceFlush) bool VirtualGPU::Queue::flush() { - std::vector memRefs; + palMemRefs_.resize(0); // Stop commands building if (Pal::Result::Success != iCmdBuffs_[cmdBufIdSlot_]->End()) { LogError("PAL failed to finalize a command buffer!"); @@ -182,12 +182,12 @@ VirtualGPU::Queue::flush() it->second &= ~FirstMemoryReference; Pal::GpuMemoryRef memRef = {}; memRef.pGpuMemory = it->first; - memRefs.push_back(memRef); + palMemRefs_.push_back(memRef); } } - if (memRefs.size() != 0) { - iDev_->AddGpuMemoryReferences(memRefs.size(), &memRefs[0], iQueue_, + if (palMemRefs_.size() != 0) { + iDev_->AddGpuMemoryReferences(palMemRefs_.size(), &palMemRefs_[0], iQueue_, Pal::GpuMemoryRefCantTrim); } @@ -257,20 +257,19 @@ VirtualGPU::Queue::flush() return false; } - memRefs.clear(); - std::vector iMems; + palMems_.resize(0); // Remove old memory references for (auto it = memReferences_.begin(); it != memReferences_.end();) { if (it->second == cmdBufIdSlot_) { - iMems.push_back(it->first); + palMems_.push_back(it->first); it = memReferences_.erase(it); } else { ++it; } } - if (iMems.size() != 0) { - iDev_->RemoveGpuMemoryReferences(iMems.size(), &iMems[0], iQueue_); + if (palMems_.size() != 0) { + iDev_->RemoveGpuMemoryReferences(palMems_.size(), &palMems_[0], iQueue_); } return true; @@ -484,7 +483,7 @@ VirtualGPU::addXferWrite(Memory& memory) { if (xferWriteBuffers_.size() > 7) { dev().xferWrite().release(*this, *xferWriteBuffers_.front()); - xferWriteBuffers_.pop_front(); + xferWriteBuffers_.erase(xferWriteBuffers_.begin()); } // Delay destruction @@ -497,7 +496,7 @@ VirtualGPU::releaseXferWrite() for (auto& memory : xferWriteBuffers_) { dev().xferWrite().release(*this, *memory); } - xferWriteBuffers_.clear(); + xferWriteBuffers_.resize(0); } void @@ -506,7 +505,7 @@ VirtualGPU::addPinnedMem(amd::Memory* mem) if (nullptr == findPinnedMem(mem->getHostMem(), mem->getSize())) { if (pinnedMems_.size() > 7) { pinnedMems_.front()->release(); - pinnedMems_.pop_front(); + pinnedMems_.erase(pinnedMems_.begin()); } // Start operation, since we should release mem object @@ -523,7 +522,7 @@ VirtualGPU::releasePinnedMem() for (auto& amdMemory : pinnedMems_) { amdMemory->release(); } - pinnedMems_.clear(); + pinnedMems_.resize(0); } amd::Memory* @@ -876,6 +875,12 @@ VirtualGPU::~VirtualGPU() static const bool SkipScratch = false; releaseMemObjects(SkipScratch); + while (!freeCbList_.empty()) { + auto cb = freeCbList_.top(); + delete cb; + freeCbList_.pop(); + } + // Destroy printf object delete printfDbg_; @@ -1892,7 +1897,7 @@ VirtualGPU::submitKernelInternal( // Get the HSA kernel object const HSAILKernel& hsaKernel = static_cast(*(kernel.getDeviceKernel(dev()))); - std::vector memList; + dispMemList_.resize(0); bool printfEnabled = (hsaKernel.printfInfo().size() > 0) ? true:false; if (!printfDbgHSA().init(*this, printfEnabled )) { @@ -1901,7 +1906,7 @@ VirtualGPU::submitKernelInternal( } // Check memory dependency and SVM objects - if (!processMemObjectsHSA(kernel, parameters, nativeMem, &memList)) { + if (!processMemObjectsHSA(kernel, parameters, nativeMem)) { LogError("Wrong memory objects!"); return false; } @@ -1927,9 +1932,9 @@ VirtualGPU::submitKernelInternal( vmDefQueue = gpuDefQueue->virtualQueue_->vmAddress(); // Add memory handles before the actual dispatch - memList.push_back(gpuDefQueue->virtualQueue_); - memList.push_back(gpuDefQueue->schedParams_); - memList.push_back(hsaKernel.prog().kernelTable()); + dispMemList_.push_back(gpuDefQueue->virtualQueue_); + dispMemList_.push_back(gpuDefQueue->schedParams_); + dispMemList_.push_back(hsaKernel.prog().kernelTable()); gpuDefQueue->writeVQueueHeader(*this, hsaKernel.prog().kernelTable()->vmAddress()); } @@ -1985,7 +1990,7 @@ VirtualGPU::submitKernelInternal( // Program the kernel arguments for the GPU execution hsa_kernel_dispatch_packet_t* aqlPkt = hsaKernel.loadArguments(*this, kernel, tmpSizes, parameters, nativeMem, - vmDefQueue, &vmParentWrap, memList); + vmDefQueue, &vmParentWrap, dispMemList_); if (nullptr == aqlPkt) { LogError("Couldn't load kernel arguments"); return false; @@ -1995,12 +2000,12 @@ VirtualGPU::submitKernelInternal( // Check if the device allocated more registers than the old setup if (hsaKernel.workGroupInfo()->scratchRegs_ > 0) { scratch = dev().scratch(hwRing()); - memList.push_back(scratch->memObj_); + dispMemList_.push_back(scratch->memObj_); } // Add GSL handle to the memory list for VidMM - for (uint i = 0; i < memList.size(); ++i) { - addVmMemory(memList[i]); + for (uint i = 0; i < dispMemList_.size(); ++i) { + addVmMemory(dispMemList_[i]); } // HW Debug for the kernel? @@ -2165,7 +2170,7 @@ VirtualGPU::submitKernelInternal( param->scratch = scratchBuf->vmAddress(); param->numMaxWaves = 32 * dev().info().maxComputeUnits_; param->scratchOffset = dev().scratch(gpuDefQueue->hwRing())->offset_; - memList.push_back(scratchBuf); + dispMemList_.push_back(scratchBuf); } else { param->numMaxWaves = 0; @@ -2176,11 +2181,11 @@ VirtualGPU::submitKernelInternal( // Add all kernels in the program to the mem list. //! \note Runtime doesn't know which one will be called - hsaKernel.prog().fillResListWithKernels(memList); + hsaKernel.prog().fillResListWithKernels(dispMemList_); // Add GPU memory handle to the memory list for VidMM - for (uint i = 0; i < memList.size(); ++i) { - gpuDefQueue->addVmMemory(memList[i]); + for (uint i = 0; i < dispMemList_.size(); ++i) { + gpuDefQueue->addVmMemory(dispMemList_[i]); } Pal::gpusize signalAddr = gpuDefQueue->schedParams_->vmAddress() + @@ -2195,8 +2200,8 @@ VirtualGPU::submitKernelInternal( gpuDefQueue->eventEnd(MainEngine, gpuEvent, ForceSubmitFirst); // Set GPU event for the used resources - for (uint i = 0; i < memList.size(); ++i) { - memList[i]->setBusy(*gpuDefQueue, gpuEvent); + for (uint i = 0; i < dispMemList_.size(); ++i) { + dispMemList_[i]->setBusy(*gpuDefQueue, gpuEvent); } if (dev().settings().useDeviceQueue_) { @@ -2218,8 +2223,8 @@ VirtualGPU::submitKernelInternal( } // Set GPU event for the used resources - for (uint i = 0; i < memList.size(); ++i) { - memList[i]->setBusy(*this, gpuEvent); + for (uint i = 0; i < dispMemList_.size(); ++i) { + dispMemList_[i]->setBusy(*this, gpuEvent); } // Update the global GPU event @@ -2253,13 +2258,13 @@ VirtualGPU::submitMarker(amd::Marker& vcmd) // Loop through all outstanding command batches while (!cbList_.empty()) { - CommandBatchList::const_iterator it = cbList_.begin(); + auto cb = cbList_.top(); // Wait for completion - foundEvent = awaitCompletion(*it, vcmd.waitingEvent()); + foundEvent = awaitCompletion(cb, vcmd.waitingEvent()); // Release a command batch - delete *it; + freeCbList_.push(cb); // Remove command batch from the list - cbList_.pop_front(); + cbList_.pop(); // Early exit if we found a command if (foundEvent) break; } @@ -2724,7 +2729,17 @@ VirtualGPU::flush(amd::Command* list, bool wait) // Insert the current batch into a list if (nullptr != list) { - cb = new CommandBatch(list, cal()->events_, cal()->lastTS_); + if (!freeCbList_.empty()) { + cb = freeCbList_.top(); + } + + if (nullptr == cb) { + cb = new CommandBatch(list, cal()->events_, cal()->lastTS_); + } + else { + freeCbList_.pop(); + cb->init(list, cal()->events_, cal()->lastTS_); + } } { @@ -2743,25 +2758,25 @@ VirtualGPU::flush(amd::Command* list, bool wait) // Mark last TS as nullptr, so runtime won't process empty batches with the old TS cal_.lastTS_ = nullptr; if (nullptr != cb) { - cbList_.push_back(cb); + cbList_.push(cb); } wait |= state_.forceWait_; // Loop through all outstanding command batches while (!cbList_.empty()) { - CommandBatchList::const_iterator it = cbList_.begin(); + auto cb = cbList_.top(); // Check if command batch finished without a wait bool finished = true; for (uint i = 0; i < AllEngines; ++i) { - finished &= isDone(&(*it)->events_[i]); + finished &= isDone(&cb->events_[i]); } if (finished || wait) { // Wait for completion - awaitCompletion(*it); + awaitCompletion(cb); // Release a command batch - delete *it; + freeCbList_.push(cb); // Remove command batch from the list - cbList_.pop_front(); + cbList_.pop(); } else { // Early exit if no finished @@ -3066,8 +3081,7 @@ bool VirtualGPU::processMemObjectsHSA( const amd::Kernel& kernel, const_address params, - bool nativeMem, - std::vector* memList) + bool nativeMem) { static const bool NoAlias = true; const HSAILKernel& hsaKernel = static_cast @@ -3129,7 +3143,7 @@ VirtualGPU::processMemObjectsHSA( // Validate SVM passed in the non argument list memoryDependency().validate(*this, gpuMemory, IsReadOnly); - memList->push_back(gpuMemory); + dispMemList_.push_back(gpuMemory); } else { return false; diff --git a/rocclr/runtime/device/pal/palvirtual.hpp b/rocclr/runtime/device/pal/palvirtual.hpp index d4716f0550..fe1cc33c80 100644 --- a/rocclr/runtime/device/pal/palvirtual.hpp +++ b/rocclr/runtime/device/pal/palvirtual.hpp @@ -3,6 +3,7 @@ // #pragma once +#include #include "device/pal/paldefs.hpp" #include "device/pal/palconstbuf.hpp" #include "device/pal/palprintf.hpp" @@ -105,6 +106,8 @@ public: uint cmdCnt_; //!< Counter of commands std::map memReferences_; Util::VirtualLinearAllocator vlAlloc_; + std::vector palMemRefs_; + std::vector palMems_; }; struct CommandBatch : public amd::HeapObject @@ -118,10 +121,22 @@ public: amd::Command* head, //!< Command batch head const GpuEvent* events, //!< HW events on all engines TimeStamp* lastTS //!< Last TS in command batch - ): head_(head), lastTS_(lastTS) + ) { + init(head, events, lastTS); + } + + void init( + amd::Command* head, //!< Command batch head + const GpuEvent* events, //!< HW events on all engines + TimeStamp* lastTS //!< Last TS in command batch + ) + { + head_ = head; + lastTS_ = lastTS; memcpy(&events_, events, AllEngines * sizeof(GpuEvent)); } + }; //! The virtual GPU states @@ -511,8 +526,7 @@ private: bool processMemObjectsHSA( const amd::Kernel& kernel, //!< AMD kernel object for execution const_address params, //!< Pointer to the param's store - bool nativeMem, //!< Native memory objects - std::vector* memList //!< Memory list for KMD tracking + bool nativeMem //!< Native memory objects ); //! Common function for fill memory used by both svm Fill and non-svm fill @@ -563,11 +577,12 @@ private: DmaFlushMgmt dmaFlushMgmt_; //!< DMA flush management - std::list xferWriteBuffers_; //!< Stage write buffers - std::list pinnedMems_;//!< Pinned memory list + std::vector xferWriteBuffers_; //!< Stage write buffers + std::vector pinnedMems_;//!< Pinned memory list - typedef std::list CommandBatchList; + typedef std::stack CommandBatchList; CommandBatchList cbList_; //!< List of command batches + CommandBatchList freeCbList_; //!< List of command batches uint hwRing_; //!< HW ring used on this virtual device @@ -585,6 +600,7 @@ private: Pal::ICmdAllocator* cmdAllocator_; //!< Command buffer allocator Queue* queues_[AllEngines]; //!< HW queues for all engines MemoryRange sdmaRange_; //!< SDMA memory range for write access + std::vector dispMemList_; //!< Memory list of all mem objects used in the disaptch }; /*@}*/} // namespace pal