1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-01-21 07:53:53 +00:00

Merge branch 'navigator_stats' into 'master'

Show stats for writing and reading navmesh db queue jobs

See merge request OpenMW/openmw!2346
This commit is contained in:
psi29a 2022-08-30 21:12:54 +00:00
commit 58d08d402a
16 changed files with 146 additions and 97 deletions

View file

@ -1,6 +1,7 @@
#include <benchmark/benchmark.h> #include <benchmark/benchmark.h>
#include <components/detournavigator/navmeshtilescache.hpp> #include <components/detournavigator/navmeshtilescache.hpp>
#include <components/detournavigator/stats.hpp>
#include <components/esm3/loadland.hpp> #include <components/esm3/loadland.hpp>
#include <algorithm> #include <algorithm>

View file

@ -35,6 +35,7 @@
#include <components/detournavigator/navigator.hpp> #include <components/detournavigator/navigator.hpp>
#include <components/detournavigator/settings.hpp> #include <components/detournavigator/settings.hpp>
#include <components/detournavigator/agentbounds.hpp> #include <components/detournavigator/agentbounds.hpp>
#include <components/detournavigator/stats.hpp>
#include <components/loadinglistener/loadinglistener.hpp> #include <components/loadinglistener/loadinglistener.hpp>
@ -3992,7 +3993,7 @@ namespace MWWorld
void World::reportStats(unsigned int frameNumber, osg::Stats& stats) const void World::reportStats(unsigned int frameNumber, osg::Stats& stats) const
{ {
mNavigator->reportStats(frameNumber, stats); DetourNavigator::reportStats(mNavigator->getStats(), frameNumber, stats);
mPhysics->reportStats(frameNumber, stats); mPhysics->reportStats(frameNumber, stats);
} }

View file

@ -316,6 +316,7 @@ add_component_dir(detournavigator
recast recast
gettilespositions gettilespositions
collisionshapetype collisionshapetype
stats
) )
add_component_dir(loadinglistener add_component_dir(loadinglistener

View file

@ -15,7 +15,6 @@
#include <DetourNavMesh.h> #include <DetourNavMesh.h>
#include <osg/Stats>
#include <osg/io_utils> #include <osg/io_utils>
#include <algorithm> #include <algorithm>
@ -111,6 +110,11 @@ namespace DetourNavigator
static std::atomic_size_t nextJobId {1}; static std::atomic_size_t nextJobId {1};
return nextJobId.fetch_add(1); return nextJobId.fetch_add(1);
} }
bool isWritingDbJob(const Job& job)
{
return job.mGeneratedNavMeshData != nullptr;
}
} }
std::ostream& operator<<(std::ostream& stream, JobStatus value) std::ostream& operator<<(std::ostream& stream, JobStatus value)
@ -302,9 +306,9 @@ namespace DetourNavigator
mProcessingTiles.wait(mProcessed, [] (const auto& v) { return v.empty(); }); mProcessingTiles.wait(mProcessed, [] (const auto& v) { return v.empty(); });
} }
AsyncNavMeshUpdater::Stats AsyncNavMeshUpdater::getStats() const AsyncNavMeshUpdaterStats AsyncNavMeshUpdater::getStats() const
{ {
Stats result; AsyncNavMeshUpdaterStats result;
{ {
const std::lock_guard<std::mutex> lock(mMutex); const std::lock_guard<std::mutex> lock(mMutex);
result.mJobs = mJobs.size(); result.mJobs = mJobs.size();
@ -319,25 +323,6 @@ namespace DetourNavigator
return result; return result;
} }
void reportStats(const AsyncNavMeshUpdater::Stats& stats, unsigned int frameNumber, osg::Stats& out)
{
out.setAttribute(frameNumber, "NavMesh Jobs", static_cast<double>(stats.mJobs));
out.setAttribute(frameNumber, "NavMesh Waiting", static_cast<double>(stats.mWaiting));
out.setAttribute(frameNumber, "NavMesh Pushed", static_cast<double>(stats.mPushed));
out.setAttribute(frameNumber, "NavMesh Processing", static_cast<double>(stats.mProcessing));
if (stats.mDb.has_value())
{
out.setAttribute(frameNumber, "NavMesh DbJobs", static_cast<double>(stats.mDb->mJobs));
if (stats.mDb->mGetTileCount > 0)
out.setAttribute(frameNumber, "NavMesh DbCacheHitRate", static_cast<double>(stats.mDbGetTileHits)
/ static_cast<double>(stats.mDb->mGetTileCount) * 100.0);
}
reportStats(stats.mCache, frameNumber, out);
}
void AsyncNavMeshUpdater::process() noexcept void AsyncNavMeshUpdater::process() noexcept
{ {
Log(Debug::Debug) << "Start process navigator jobs by thread=" << std::this_thread::get_id(); Log(Debug::Debug) << "Start process navigator jobs by thread=" << std::this_thread::get_id();
@ -690,6 +675,10 @@ namespace DetourNavigator
{ {
const std::lock_guard lock(mMutex); const std::lock_guard lock(mMutex);
insertPrioritizedDbJob(job, mJobs); insertPrioritizedDbJob(job, mJobs);
if (isWritingDbJob(*job))
++mWritingJobs;
else
++mReadingJobs;
mHasJob.notify_all(); mHasJob.notify_all();
} }
@ -701,6 +690,10 @@ namespace DetourNavigator
return std::nullopt; return std::nullopt;
const JobIt job = mJobs.front(); const JobIt job = mJobs.front();
mJobs.pop_front(); mJobs.pop_front();
if (isWritingDbJob(*job))
--mWritingJobs;
else
--mReadingJobs;
return job; return job;
} }
@ -719,10 +712,10 @@ namespace DetourNavigator
mHasJob.notify_all(); mHasJob.notify_all();
} }
std::size_t DbJobQueue::size() const DbJobQueueStats DbJobQueue::getStats() const
{ {
const std::lock_guard lock(mMutex); const std::lock_guard lock(mMutex);
return mJobs.size(); return DbJobQueueStats {.mWritingJobs = mWritingJobs, .mReadingJobs = mReadingJobs};
} }
DbWorker::DbWorker(AsyncNavMeshUpdater& updater, std::unique_ptr<NavMeshDb>&& db, DbWorker::DbWorker(AsyncNavMeshUpdater& updater, std::unique_ptr<NavMeshDb>&& db,
@ -749,12 +742,12 @@ namespace DetourNavigator
mQueue.push(job); mQueue.push(job);
} }
DbWorker::Stats DbWorker::getStats() const DbWorkerStats DbWorker::getStats() const
{ {
Stats result; return DbWorkerStats {
result.mJobs = mQueue.size(); .mJobs = mQueue.getStats(),
result.mGetTileCount = mGetTileCount.load(std::memory_order_relaxed); .mGetTileCount = mGetTileCount.load(std::memory_order_relaxed)
return result; };
} }
void DbWorker::stop() void DbWorker::stop()
@ -809,7 +802,7 @@ namespace DetourNavigator
} }
}; };
if (job->mGeneratedNavMeshData != nullptr) if (isWritingDbJob(*job))
{ {
process([&] (JobIt job) { processWritingJob(job); }); process([&] (JobIt job) { processWritingJob(job); });
mUpdater.removeJob(job); mUpdater.removeJob(job);

View file

@ -12,6 +12,7 @@
#include "agentbounds.hpp" #include "agentbounds.hpp"
#include "guardednavmeshcacheitem.hpp" #include "guardednavmeshcacheitem.hpp"
#include "sharednavmeshcacheitem.hpp" #include "sharednavmeshcacheitem.hpp"
#include "stats.hpp"
#include <osg/Vec3f> #include <osg/Vec3f>
@ -88,13 +89,15 @@ namespace DetourNavigator
void stop(); void stop();
std::size_t size() const; DbJobQueueStats getStats() const;
private: private:
mutable std::mutex mMutex; mutable std::mutex mMutex;
std::condition_variable mHasJob; std::condition_variable mHasJob;
std::deque<JobIt> mJobs; std::deque<JobIt> mJobs;
bool mShouldStop = false; bool mShouldStop = false;
std::size_t mWritingJobs = 0;
std::size_t mReadingJobs = 0;
}; };
class AsyncNavMeshUpdater; class AsyncNavMeshUpdater;
@ -102,18 +105,12 @@ namespace DetourNavigator
class DbWorker class DbWorker
{ {
public: public:
struct Stats
{
std::size_t mJobs = 0;
std::size_t mGetTileCount = 0;
};
DbWorker(AsyncNavMeshUpdater& updater, std::unique_ptr<NavMeshDb>&& db, DbWorker(AsyncNavMeshUpdater& updater, std::unique_ptr<NavMeshDb>&& db,
TileVersion version, const RecastSettings& recastSettings, bool writeToDb); TileVersion version, const RecastSettings& recastSettings, bool writeToDb);
~DbWorker(); ~DbWorker();
Stats getStats() const; DbWorkerStats getStats() const;
void enqueueJob(JobIt job); void enqueueJob(JobIt job);
@ -146,17 +143,6 @@ namespace DetourNavigator
class AsyncNavMeshUpdater class AsyncNavMeshUpdater
{ {
public: public:
struct Stats
{
std::size_t mJobs = 0;
std::size_t mWaiting = 0;
std::size_t mPushed = 0;
std::size_t mProcessing = 0;
std::size_t mDbGetTileHits = 0;
std::optional<DbWorker::Stats> mDb;
NavMeshTilesCache::Stats mCache;
};
AsyncNavMeshUpdater(const Settings& settings, TileCachedRecastMeshManager& recastMeshManager, AsyncNavMeshUpdater(const Settings& settings, TileCachedRecastMeshManager& recastMeshManager,
OffMeshConnectionsManager& offMeshConnectionsManager, std::unique_ptr<NavMeshDb>&& db); OffMeshConnectionsManager& offMeshConnectionsManager, std::unique_ptr<NavMeshDb>&& db);
~AsyncNavMeshUpdater(); ~AsyncNavMeshUpdater();
@ -169,7 +155,7 @@ namespace DetourNavigator
void stop(); void stop();
Stats getStats() const; AsyncNavMeshUpdaterStats getStats() const;
void enqueueJob(JobIt job); void enqueueJob(JobIt job);
@ -227,8 +213,6 @@ namespace DetourNavigator
inline void waitUntilAllJobsDone(); inline void waitUntilAllJobsDone();
}; };
void reportStats(const AsyncNavMeshUpdater::Stats& stats, unsigned int frameNumber, osg::Stats& out);
} }
#endif #endif

View file

@ -23,15 +23,11 @@ namespace Loading
class Listener; class Listener;
} }
namespace osg
{
class Stats;
}
namespace DetourNavigator namespace DetourNavigator
{ {
struct Settings; struct Settings;
struct AgentBounds; struct AgentBounds;
struct Stats;
struct ObjectShapes struct ObjectShapes
{ {
@ -181,7 +177,7 @@ namespace DetourNavigator
virtual const Settings& getSettings() const = 0; virtual const Settings& getSettings() const = 0;
virtual void reportStats(unsigned int frameNumber, osg::Stats& stats) const = 0; virtual Stats getStats() const = 0;
virtual RecastMeshTiles getRecastMeshTiles() const = 0; virtual RecastMeshTiles getRecastMeshTiles() const = 0;

View file

@ -1,5 +1,6 @@
#include "navigatorimpl.hpp" #include "navigatorimpl.hpp"
#include "settingsutils.hpp" #include "settingsutils.hpp"
#include "stats.hpp"
#include <components/debug/debuglog.hpp> #include <components/debug/debuglog.hpp>
#include <components/esm3/loadpgrd.hpp> #include <components/esm3/loadpgrd.hpp>
@ -173,9 +174,9 @@ namespace DetourNavigator
return mSettings; return mSettings;
} }
void NavigatorImpl::reportStats(unsigned int frameNumber, osg::Stats& stats) const Stats NavigatorImpl::getStats() const
{ {
mNavMeshManager.reportStats(frameNumber, stats); return mNavMeshManager.getStats();
} }
RecastMeshTiles NavigatorImpl::getRecastMeshTiles() const RecastMeshTiles NavigatorImpl::getRecastMeshTiles() const

View file

@ -58,7 +58,7 @@ namespace DetourNavigator
const Settings& getSettings() const override; const Settings& getSettings() const override;
void reportStats(unsigned int frameNumber, osg::Stats& stats) const override; Stats getStats() const override;
RecastMeshTiles getRecastMeshTiles() const override; RecastMeshTiles getRecastMeshTiles() const override;

View file

@ -3,6 +3,7 @@
#include "navigator.hpp" #include "navigator.hpp"
#include "settings.hpp" #include "settings.hpp"
#include "stats.hpp"
namespace Loading namespace Loading
{ {
@ -66,7 +67,7 @@ namespace DetourNavigator
return mDefaultSettings; return mDefaultSettings;
} }
void reportStats(unsigned int /*frameNumber*/, osg::Stats& /*stats*/) const override {} Stats getStats() const override { return Stats {}; }
RecastMeshTiles getRecastMeshTiles() const override RecastMeshTiles getRecastMeshTiles() const override
{ {

View file

@ -268,9 +268,9 @@ namespace DetourNavigator
return mCache; return mCache;
} }
void NavMeshManager::reportStats(unsigned int frameNumber, osg::Stats& stats) const Stats NavMeshManager::getStats() const
{ {
DetourNavigator::reportStats(mAsyncNavMeshUpdater.getStats(), frameNumber, stats); return Stats {.mUpdater = mAsyncNavMeshUpdater.getStats()};
} }
RecastMeshTiles NavMeshManager::getRecastMeshTiles() const RecastMeshTiles NavMeshManager::getRecastMeshTiles() const

View file

@ -58,7 +58,7 @@ namespace DetourNavigator
std::map<AgentBounds, SharedNavMeshCacheItem> getNavMeshes() const; std::map<AgentBounds, SharedNavMeshCacheItem> getNavMeshes() const;
void reportStats(unsigned int frameNumber, osg::Stats& stats) const; Stats getStats() const;
RecastMeshTiles getRecastMeshTiles() const; RecastMeshTiles getRecastMeshTiles() const;

View file

@ -1,6 +1,5 @@
#include "navmeshtilescache.hpp" #include "navmeshtilescache.hpp"
#include "stats.hpp"
#include <osg/Stats>
#include <cstring> #include <cstring>
@ -65,9 +64,9 @@ namespace DetourNavigator
return Value(*this, iterator); return Value(*this, iterator);
} }
NavMeshTilesCache::Stats NavMeshTilesCache::getStats() const NavMeshTilesCacheStats NavMeshTilesCache::getStats() const
{ {
Stats result; NavMeshTilesCacheStats result;
{ {
const std::lock_guard<std::mutex> lock(mMutex); const std::lock_guard<std::mutex> lock(mMutex);
result.mNavMeshCacheSize = mUsedNavMeshDataSize; result.mNavMeshCacheSize = mUsedNavMeshDataSize;
@ -79,15 +78,6 @@ namespace DetourNavigator
return result; return result;
} }
void reportStats(const NavMeshTilesCache::Stats& stats, unsigned int frameNumber, osg::Stats& out)
{
out.setAttribute(frameNumber, "NavMesh CacheSize", static_cast<double>(stats.mNavMeshCacheSize));
out.setAttribute(frameNumber, "NavMesh UsedTiles", static_cast<double>(stats.mUsedNavMeshTiles));
out.setAttribute(frameNumber, "NavMesh CachedTiles", static_cast<double>(stats.mCachedNavMeshTiles));
if (stats.mGetCount > 0)
out.setAttribute(frameNumber, "NavMesh CacheHitRate", static_cast<double>(stats.mHitCount) / stats.mGetCount * 100.0);
}
void NavMeshTilesCache::removeLeastRecentlyUsed() void NavMeshTilesCache::removeLeastRecentlyUsed()
{ {
const auto& item = mFreeItems.back(); const auto& item = mFreeItems.back();

View file

@ -14,11 +14,6 @@
#include <cstring> #include <cstring>
#include <vector> #include <vector>
namespace osg
{
class Stats;
}
namespace DetourNavigator namespace DetourNavigator
{ {
struct RecastMeshData struct RecastMeshData
@ -47,6 +42,8 @@ namespace DetourNavigator
< std::tie(rhs.mMesh, rhs.mWater, rhs.mHeightfields, rhs.mFlatHeightfields); < std::tie(rhs.mMesh, rhs.mWater, rhs.mHeightfields, rhs.mFlatHeightfields);
} }
struct NavMeshTilesCacheStats;
class NavMeshTilesCache class NavMeshTilesCache
{ {
public: public:
@ -126,15 +123,6 @@ namespace DetourNavigator
ItemIterator mIterator; ItemIterator mIterator;
}; };
struct Stats
{
std::size_t mNavMeshCacheSize;
std::size_t mUsedNavMeshTiles;
std::size_t mCachedNavMeshTiles;
std::size_t mHitCount;
std::size_t mGetCount;
};
NavMeshTilesCache(const std::size_t maxNavMeshDataSize); NavMeshTilesCache(const std::size_t maxNavMeshDataSize);
Value get(const AgentBounds& agentBounds, const TilePosition& changedTile, Value get(const AgentBounds& agentBounds, const TilePosition& changedTile,
@ -143,7 +131,7 @@ namespace DetourNavigator
Value set(const AgentBounds& agentBounds, const TilePosition& changedTile, Value set(const AgentBounds& agentBounds, const TilePosition& changedTile,
const RecastMesh& recastMesh, std::unique_ptr<PreparedNavMeshData>&& value); const RecastMesh& recastMesh, std::unique_ptr<PreparedNavMeshData>&& value);
Stats getStats() const; NavMeshTilesCacheStats getStats() const;
private: private:
mutable std::mutex mMutex; mutable std::mutex mMutex;
@ -162,8 +150,6 @@ namespace DetourNavigator
void releaseItem(ItemIterator iterator); void releaseItem(ItemIterator iterator);
}; };
void reportStats(const NavMeshTilesCache::Stats& stats, unsigned int frameNumber, osg::Stats& out);
} }
#endif #endif

View file

@ -0,0 +1,40 @@
#include "stats.hpp"
#include <osg/Stats>
namespace DetourNavigator
{
namespace
{
void reportStats(const AsyncNavMeshUpdaterStats& stats, unsigned int frameNumber, osg::Stats& out)
{
out.setAttribute(frameNumber, "NavMesh Jobs", static_cast<double>(stats.mJobs));
out.setAttribute(frameNumber, "NavMesh Waiting", static_cast<double>(stats.mWaiting));
out.setAttribute(frameNumber, "NavMesh Pushed", static_cast<double>(stats.mPushed));
out.setAttribute(frameNumber, "NavMesh Processing", static_cast<double>(stats.mProcessing));
if (stats.mDb.has_value())
{
out.setAttribute(frameNumber, "NavMesh DbJobs Write", static_cast<double>(stats.mDb->mJobs.mWritingJobs));
out.setAttribute(frameNumber, "NavMesh DbJobs Read", static_cast<double>(stats.mDb->mJobs.mReadingJobs));
if (stats.mDb->mGetTileCount > 0)
out.setAttribute(frameNumber, "NavMesh DbCacheHitRate", static_cast<double>(stats.mDbGetTileHits)
/ static_cast<double>(stats.mDb->mGetTileCount) * 100.0);
}
out.setAttribute(frameNumber, "NavMesh CacheSize", static_cast<double>(stats.mCache.mNavMeshCacheSize));
out.setAttribute(frameNumber, "NavMesh UsedTiles", static_cast<double>(stats.mCache.mUsedNavMeshTiles));
out.setAttribute(frameNumber, "NavMesh CachedTiles", static_cast<double>(stats.mCache.mCachedNavMeshTiles));
if (stats.mCache.mGetCount > 0)
out.setAttribute(frameNumber, "NavMesh CacheHitRate", static_cast<double>(stats.mCache.mHitCount)
/ stats.mCache.mGetCount * 100.0);
}
}
void reportStats(const Stats& stats, unsigned int frameNumber, osg::Stats& out)
{
if (stats.mUpdater.has_value())
reportStats(*stats.mUpdater, frameNumber, out);
}
}

View file

@ -0,0 +1,54 @@
#ifndef OPENMW_COMPONENTS_DETOURNAVIGATOR_STATS_H
#define OPENMW_COMPONENTS_DETOURNAVIGATOR_STATS_H
#include <cstddef>
#include <optional>
namespace osg
{
class Stats;
}
namespace DetourNavigator
{
struct DbJobQueueStats
{
std::size_t mWritingJobs = 0;
std::size_t mReadingJobs = 0;
};
struct DbWorkerStats
{
DbJobQueueStats mJobs;
std::size_t mGetTileCount = 0;
};
struct NavMeshTilesCacheStats
{
std::size_t mNavMeshCacheSize = 0;
std::size_t mUsedNavMeshTiles = 0;
std::size_t mCachedNavMeshTiles = 0;
std::size_t mHitCount = 0;
std::size_t mGetCount = 0;
};
struct AsyncNavMeshUpdaterStats
{
std::size_t mJobs = 0;
std::size_t mWaiting = 0;
std::size_t mPushed = 0;
std::size_t mProcessing = 0;
std::size_t mDbGetTileHits = 0;
std::optional<DbWorkerStats> mDb;
NavMeshTilesCacheStats mCache;
};
struct Stats
{
std::optional<AsyncNavMeshUpdaterStats> mUpdater;
};
void reportStats(const Stats& stats, unsigned int frameNumber, osg::Stats& out);
}
#endif

View file

@ -439,7 +439,8 @@ void StatsHandler::setUpScene(osgViewer::ViewerBase *viewer)
"NavMesh Waiting", "NavMesh Waiting",
"NavMesh Pushed", "NavMesh Pushed",
"NavMesh Processing", "NavMesh Processing",
"NavMesh DbJobs", "NavMesh DbJobs Write",
"NavMesh DbJobs Read",
"NavMesh DbCacheHitRate", "NavMesh DbCacheHitRate",
"NavMesh CacheSize", "NavMesh CacheSize",
"NavMesh UsedTiles", "NavMesh UsedTiles",