mirror of
https://github.com/doitsujin/dxvk.git
synced 2024-12-11 10:24:10 +01:00
[dxvk] Implement shared cache statistics
This commit is contained in:
parent
2722a41675
commit
428b1087a0
@ -235,8 +235,9 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void DxvkDevice::getMemoryAllocationStats(DxvkMemoryAllocationStats& stats) {
|
DxvkSharedAllocationCacheStats DxvkDevice::getMemoryAllocationStats(DxvkMemoryAllocationStats& stats) {
|
||||||
return m_objects.memoryManager().getAllocationStats(stats);
|
m_objects.memoryManager().getAllocationStats(stats);
|
||||||
|
return m_objects.memoryManager().getAllocationCacheStats();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -408,8 +408,9 @@ namespace dxvk {
|
|||||||
*
|
*
|
||||||
* Expensive, should be used with caution.
|
* Expensive, should be used with caution.
|
||||||
* \param [out] stats Allocation statistics
|
* \param [out] stats Allocation statistics
|
||||||
|
* \returns Shared allocation cache stats
|
||||||
*/
|
*/
|
||||||
void getMemoryAllocationStats(DxvkMemoryAllocationStats& stats);
|
DxvkSharedAllocationCacheStats getMemoryAllocationStats(DxvkMemoryAllocationStats& stats);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Retreves current frame ID
|
* \brief Retreves current frame ID
|
||||||
|
@ -286,14 +286,19 @@ namespace dxvk {
|
|||||||
|
|
||||||
// If there's a list ready for us, take the whole thing
|
// If there's a list ready for us, take the whole thing
|
||||||
std::unique_lock poolLock(m_poolMutex);
|
std::unique_lock poolLock(m_poolMutex);
|
||||||
|
m_numRequests += 1u;
|
||||||
|
|
||||||
auto& pool = m_pools[poolIndex];
|
auto& pool = m_pools[poolIndex];
|
||||||
|
|
||||||
if (!pool.listCount)
|
if (!pool.listCount) {
|
||||||
|
m_numMisses += 1u;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
if (!(--pool.listCount))
|
if (!(--pool.listCount))
|
||||||
pool.drainTime = high_resolution_clock::now();
|
pool.drainTime = high_resolution_clock::now();
|
||||||
|
|
||||||
|
m_cacheSize -= PoolCapacityInBytes;
|
||||||
return std::exchange(pool.lists[pool.listCount], nullptr);
|
return std::exchange(pool.lists[pool.listCount], nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -323,6 +328,10 @@ namespace dxvk {
|
|||||||
|
|
||||||
if (likely(pool.listCount < PoolSize)) {
|
if (likely(pool.listCount < PoolSize)) {
|
||||||
pool.lists[pool.listCount++] = allocation;
|
pool.lists[pool.listCount++] = allocation;
|
||||||
|
|
||||||
|
if ((m_cacheSize += PoolCapacityInBytes) > m_maxCacheSize)
|
||||||
|
m_maxCacheSize = m_cacheSize;
|
||||||
|
|
||||||
return nullptr;
|
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(
|
void DxvkSharedAllocationCache::cleanupUnusedFromLockedAllocator(
|
||||||
high_resolution_clock::time_point time) {
|
high_resolution_clock::time_point time) {
|
||||||
std::unique_lock poolLock(m_poolMutex);
|
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(
|
bool DxvkMemoryAllocator::getBufferMemoryRequirements(
|
||||||
const VkBufferCreateInfo& createInfo,
|
const VkBufferCreateInfo& createInfo,
|
||||||
VkMemoryRequirements2& memoryRequirements) const {
|
VkMemoryRequirements2& memoryRequirements) const {
|
||||||
|
@ -770,8 +770,6 @@ namespace dxvk {
|
|||||||
* context classes in order to reduce lock contention.
|
* context classes in order to reduce lock contention.
|
||||||
*/
|
*/
|
||||||
class DxvkLocalAllocationCache {
|
class DxvkLocalAllocationCache {
|
||||||
constexpr static VkDeviceSize PoolCapacityInBytes = 4u * DxvkPageAllocator::PageSize;
|
|
||||||
|
|
||||||
friend DxvkMemoryAllocator;
|
friend DxvkMemoryAllocator;
|
||||||
public:
|
public:
|
||||||
// Cache allocations up to 128 kiB
|
// Cache allocations up to 128 kiB
|
||||||
@ -780,6 +778,8 @@ namespace dxvk {
|
|||||||
constexpr static VkDeviceSize MinSize = DxvkPoolAllocator::MinSize;
|
constexpr static VkDeviceSize MinSize = DxvkPoolAllocator::MinSize;
|
||||||
constexpr static VkDeviceSize MaxSize = MinSize << (PoolCount - 1u);
|
constexpr static VkDeviceSize MaxSize = MinSize << (PoolCount - 1u);
|
||||||
|
|
||||||
|
constexpr static VkDeviceSize PoolCapacityInBytes = 4u * DxvkPageAllocator::PageSize;
|
||||||
|
|
||||||
DxvkLocalAllocationCache() = default;
|
DxvkLocalAllocationCache() = default;
|
||||||
|
|
||||||
DxvkLocalAllocationCache(
|
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
|
* \brief Shared allocation cache
|
||||||
*
|
*
|
||||||
@ -870,6 +886,8 @@ namespace dxvk {
|
|||||||
constexpr static uint32_t PoolCount = DxvkLocalAllocationCache::PoolCount;
|
constexpr static uint32_t PoolCount = DxvkLocalAllocationCache::PoolCount;
|
||||||
constexpr static uint32_t PoolSize = env::is32BitHostPlatform() ? 6u : 12u;
|
constexpr static uint32_t PoolSize = env::is32BitHostPlatform() ? 6u : 12u;
|
||||||
|
|
||||||
|
constexpr static VkDeviceSize PoolCapacityInBytes = DxvkLocalAllocationCache::PoolCapacityInBytes;
|
||||||
|
|
||||||
friend DxvkMemoryAllocator;
|
friend DxvkMemoryAllocator;
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -898,6 +916,22 @@ namespace dxvk {
|
|||||||
DxvkResourceAllocation* freeAllocation(
|
DxvkResourceAllocation* freeAllocation(
|
||||||
DxvkResourceAllocation* allocation);
|
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:
|
private:
|
||||||
|
|
||||||
struct FreeList {
|
struct FreeList {
|
||||||
@ -923,8 +957,11 @@ namespace dxvk {
|
|||||||
dxvk::mutex m_poolMutex;
|
dxvk::mutex m_poolMutex;
|
||||||
std::array<Pool, PoolCount> m_pools = { };
|
std::array<Pool, PoolCount> m_pools = { };
|
||||||
|
|
||||||
void cleanupUnusedFromLockedAllocator(
|
uint32_t m_numRequests = 0u;
|
||||||
high_resolution_clock::time_point time);
|
uint32_t m_numMisses = 0u;
|
||||||
|
|
||||||
|
VkDeviceSize m_cacheSize = 0u;
|
||||||
|
VkDeviceSize m_maxCacheSize = 0u;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1066,6 +1103,14 @@ namespace dxvk {
|
|||||||
*/
|
*/
|
||||||
void getAllocationStats(DxvkMemoryAllocationStats& stats);
|
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
|
* \brief Queries buffer memory requirements
|
||||||
*
|
*
|
||||||
|
Loading…
Reference in New Issue
Block a user