1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2024-12-02 01:24:11 +01:00

[dxvk] Implement shared cache statistics

This commit is contained in:
Philip Rebohle 2024-09-24 23:40:17 +02:00 committed by Philip Rebohle
parent 2722a41675
commit 428b1087a0
4 changed files with 98 additions and 9 deletions

View File

@ -235,8 +235,9 @@ namespace dxvk {
}
void DxvkDevice::getMemoryAllocationStats(DxvkMemoryAllocationStats& stats) {
return m_objects.memoryManager().getAllocationStats(stats);
DxvkSharedAllocationCacheStats DxvkDevice::getMemoryAllocationStats(DxvkMemoryAllocationStats& stats) {
m_objects.memoryManager().getAllocationStats(stats);
return m_objects.memoryManager().getAllocationCacheStats();
}

View File

@ -408,8 +408,9 @@ namespace dxvk {
*
* Expensive, should be used with caution.
* \param [out] stats Allocation statistics
* \returns Shared allocation cache stats
*/
void getMemoryAllocationStats(DxvkMemoryAllocationStats& stats);
DxvkSharedAllocationCacheStats getMemoryAllocationStats(DxvkMemoryAllocationStats& stats);
/**
* \brief Retreves current frame ID

View File

@ -286,14 +286,19 @@ namespace dxvk {
// If there's a list ready for us, take the whole thing
std::unique_lock poolLock(m_poolMutex);
m_numRequests += 1u;
auto& pool = m_pools[poolIndex];
if (!pool.listCount)
if (!pool.listCount) {
m_numMisses += 1u;
return nullptr;
}
if (!(--pool.listCount))
pool.drainTime = high_resolution_clock::now();
m_cacheSize -= PoolCapacityInBytes;
return std::exchange(pool.lists[pool.listCount], nullptr);
}
@ -323,6 +328,10 @@ namespace dxvk {
if (likely(pool.listCount < PoolSize)) {
pool.lists[pool.listCount++] = allocation;
if ((m_cacheSize += PoolCapacityInBytes) > m_maxCacheSize)
m_maxCacheSize = m_cacheSize;
return nullptr;
}
@ -332,6 +341,21 @@ namespace dxvk {
}
DxvkSharedAllocationCacheStats DxvkSharedAllocationCache::getStats() {
std::unique_lock poolLock(m_poolMutex);
DxvkSharedAllocationCacheStats result = { };
result.requestCount = m_numRequests;
result.missCount = m_numMisses;
result.size = m_maxCacheSize;
m_numRequests = 0u;
m_numMisses = 0u;
m_maxCacheSize = 0u;
return result;
}
void DxvkSharedAllocationCache::cleanupUnusedFromLockedAllocator(
high_resolution_clock::time_point time) {
std::unique_lock poolLock(m_poolMutex);
@ -1571,6 +1595,24 @@ namespace dxvk {
}
DxvkSharedAllocationCacheStats DxvkMemoryAllocator::getAllocationCacheStats() const {
DxvkSharedAllocationCacheStats result = { };
for (uint32_t i = 0; i < m_memTypeCount; i++) {
const auto& type = m_memTypes[i];
if (type.sharedCache) {
DxvkSharedAllocationCacheStats stats = type.sharedCache->getStats();
result.requestCount += stats.requestCount;
result.missCount += stats.missCount;
result.size += stats.size;
}
}
return result;
}
bool DxvkMemoryAllocator::getBufferMemoryRequirements(
const VkBufferCreateInfo& createInfo,
VkMemoryRequirements2& memoryRequirements) const {

View File

@ -770,8 +770,6 @@ namespace dxvk {
* context classes in order to reduce lock contention.
*/
class DxvkLocalAllocationCache {
constexpr static VkDeviceSize PoolCapacityInBytes = 4u * DxvkPageAllocator::PageSize;
friend DxvkMemoryAllocator;
public:
// Cache allocations up to 128 kiB
@ -780,6 +778,8 @@ namespace dxvk {
constexpr static VkDeviceSize MinSize = DxvkPoolAllocator::MinSize;
constexpr static VkDeviceSize MaxSize = MinSize << (PoolCount - 1u);
constexpr static VkDeviceSize PoolCapacityInBytes = 4u * DxvkPageAllocator::PageSize;
DxvkLocalAllocationCache() = default;
DxvkLocalAllocationCache(
@ -860,6 +860,22 @@ namespace dxvk {
};
/**
* \brief Allocation cache stats
*
* Keeps track of the number of requests as
* well as the total size of the cache.
*/
struct DxvkSharedAllocationCacheStats {
/// Total number of requests
uint32_t requestCount = 0u;
/// Number of failed requests
uint32_t missCount = 0u;
/// Cache size, in bytes
VkDeviceSize size = 0u;
};
/**
* \brief Shared allocation cache
*
@ -870,6 +886,8 @@ namespace dxvk {
constexpr static uint32_t PoolCount = DxvkLocalAllocationCache::PoolCount;
constexpr static uint32_t PoolSize = env::is32BitHostPlatform() ? 6u : 12u;
constexpr static VkDeviceSize PoolCapacityInBytes = DxvkLocalAllocationCache::PoolCapacityInBytes;
friend DxvkMemoryAllocator;
public:
@ -898,6 +916,22 @@ namespace dxvk {
DxvkResourceAllocation* freeAllocation(
DxvkResourceAllocation* allocation);
/**
* \brief Queries statistics
* \returns Cache statistics
*/
DxvkSharedAllocationCacheStats getStats();
/**
* \brief Frees unused memory
*
* Periodically called from the worker to free some
* memory that has not been used in some time.
* \param [in] time Current time
*/
void cleanupUnusedFromLockedAllocator(
high_resolution_clock::time_point time);
private:
struct FreeList {
@ -923,8 +957,11 @@ namespace dxvk {
dxvk::mutex m_poolMutex;
std::array<Pool, PoolCount> m_pools = { };
void cleanupUnusedFromLockedAllocator(
high_resolution_clock::time_point time);
uint32_t m_numRequests = 0u;
uint32_t m_numMisses = 0u;
VkDeviceSize m_cacheSize = 0u;
VkDeviceSize m_maxCacheSize = 0u;
};
@ -1056,7 +1093,7 @@ namespace dxvk {
* \returns Memory stats for this heap
*/
DxvkMemoryStats getMemoryStats(uint32_t heap) const;
/**
* \brief Retrieves detailed memory statistics
*
@ -1066,6 +1103,14 @@ namespace dxvk {
*/
void getAllocationStats(DxvkMemoryAllocationStats& stats);
/**
* \brief Queries shared cache stats
*
* Returns statistics for all shared caches.
* \returns Shared cache stats
*/
DxvkSharedAllocationCacheStats getAllocationCacheStats() const;
/**
* \brief Queries buffer memory requirements
*