diff --git a/Profiler/Core/FastConcurrentQueue.cs b/Profiler/Core/FastConcurrentQueue.cs deleted file mode 100644 index ee1b2b5..0000000 --- a/Profiler/Core/FastConcurrentQueue.cs +++ /dev/null @@ -1,132 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Threading; -using NLog; - -namespace Profiler.Core -{ - internal sealed class FastConcurrentQueue - { - readonly NullableArrayList> _queues; - - public FastConcurrentQueue() - { - _queues = new NullableArrayList>(100); - } - - public bool TryDequeue(ref int index, out T element) - { - while (index < _queues.Length) - { - if (_queues[index] is { } queuePair && - queuePair.TryDequeue(out element)) - { - return true; - } - - index += 1; - } - - element = default; - return false; - } - - public void Enqueue(in T result) - { - var index = Thread.CurrentThread.ManagedThreadId; - - if (!_queues.HasElementAt(index)) - { - _queues.InsertElementAt(index, new QueuePair()); - } - - _queues[index]?.Enqueue(result); - } - - public void Alternate() - { - for (var i = 0; i < _queues.Length; i++) - { - _queues[i]?.Alternate(); - } - } - } - - internal sealed class QueuePair - { - readonly Queue _queue0; - readonly Queue _queue1; - readonly bool _initialized; - bool _switch; - - public QueuePair() - { - _initialized = true; - _queue0 = new Queue(); - _queue1 = new Queue(); - } - - public void Alternate() - { - _switch = !_switch; - } - - public void Enqueue(in T element) - { - if (!_initialized) return; //very rare - - var current = _switch ? _queue0 : _queue1; - current.Enqueue(element); - } - - public bool TryDequeue(out T element) - { - element = default; - if (!_initialized) return false; //very rare - - var current = !_switch ? _queue0 : _queue1; - return current.TryDequeue(out element); - } - } - - internal sealed class NullableArrayList where T : class - { - readonly ILogger Log = LogManager.GetCurrentClassLogger(); - - T[] _array; - - public NullableArrayList(int initialLength) - { - _array = new T[initialLength]; - } - - public T this[int index] => _array[index]; - public int Length => _array.Length; - - public bool HasElementAt(int index) - { - return index < _array.Length && _array[index] != null; - } - - public void InsertElementAt(int index, T element) - { - if (index >= _array.Length) - { - Expand(index + 1); - } - - _array[index] = element; - Log.Debug($"INSERT {index}"); - } - - void Expand(int length) - { - var maxLength = Math.Max(length, _array.Length); // todo pick next 2^n - var array = new T[maxLength]; - Array.Copy(_array, array, _array.Length); - _array = array; // there's a shallow chance you miss something here - - Log.Debug($"EXPAND {length}"); - } - } -} \ No newline at end of file diff --git a/Profiler/Core/ProfilerResultQueue.cs b/Profiler/Core/ProfilerResultQueue.cs index 14235d1..efa0bfa 100644 --- a/Profiler/Core/ProfilerResultQueue.cs +++ b/Profiler/Core/ProfilerResultQueue.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Concurrent; using System.Threading; using System.Threading.Tasks; using NLog; @@ -13,12 +14,12 @@ namespace Profiler.Core public static class ProfilerResultQueue { static readonly ILogger Log = LogManager.GetCurrentClassLogger(); - static readonly FastConcurrentQueue _profilerResults; + static readonly ConcurrentQueue _profilerResults; static readonly ConcurrentCachingList _profilers; static ProfilerResultQueue() { - _profilerResults = new FastConcurrentQueue(); + _profilerResults = new ConcurrentQueue(); _profilers = new ConcurrentCachingList(); } @@ -35,8 +36,6 @@ public static IDisposable Profile(IProfiler observer) internal static void Enqueue(in ProfilerResult result) { - if (_profilers.Count == 0) return; - _profilerResults.Enqueue(result); } @@ -44,26 +43,41 @@ internal static async Task Start(CancellationToken canceller) { while (!canceller.IsCancellationRequested) { - _profilerResults.Alternate(); - _profilers.ApplyChanges(); - - var index = 0; - while (_profilerResults.TryDequeue(ref index, out var result)) + try { - foreach (var profiler in _profilers) + _profilers.ApplyChanges(); + + var dequeued = false; + while (_profilerResults.TryDequeue(out var result)) { - try + dequeued = true; + foreach (var profiler in _profilers) { - profiler.ReceiveProfilerResult(result); - } - catch (Exception e) - { - Log.Error($"{profiler}: {e.Message}"); + try + { + profiler.ReceiveProfilerResult(result); + } + catch (Exception e) + { + Log.Error($"{profiler}: {e.Message}"); + } } } - } - await Task.Delay(TimeSpan.FromSeconds(.1f), canceller); + if (!dequeued) + { + await Task.Delay(TimeSpan.FromSeconds(.1f), canceller); + } + } + catch (OperationCanceledException) when (canceller.IsCancellationRequested) + { + break; + } + catch (Exception e) + { + Log.Warn(e, "Profiler consumer loop crashed; restarting after delay"); + await Task.Delay(TimeSpan.FromSeconds(1), canceller); + } } } diff --git a/Profiler/Core/StringIndexer.cs b/Profiler/Core/StringIndexer.cs index 125c756..ad42fdd 100644 --- a/Profiler/Core/StringIndexer.cs +++ b/Profiler/Core/StringIndexer.cs @@ -11,6 +11,7 @@ internal sealed class StringIndexer public static readonly StringIndexer Instance = new StringIndexer(); readonly List _mapping; + readonly object _lock = new object(); StringIndexer() { @@ -24,21 +25,27 @@ public int IndexOf(string methodName) throw new Exception("method name null"); } - var existingIndex = _mapping.IndexOf(methodName); - if (existingIndex >= 0) return existingIndex; + lock (_lock) + { + var existingIndex = _mapping.IndexOf(methodName); + if (existingIndex >= 0) return existingIndex; - _mapping.Add(methodName); - return _mapping.Count - 1; + _mapping.Add(methodName); + return _mapping.Count - 1; + } } public string StringAt(int index) { - if (index >= _mapping.Count) + lock (_lock) { - throw new IndexOutOfRangeException($"length: {_mapping.Count}, given index: {index}"); - } + if (index >= _mapping.Count) + { + throw new IndexOutOfRangeException($"length: {_mapping.Count}, given index: {index}"); + } - return _mapping[index]; + return _mapping[index]; + } } } } \ No newline at end of file diff --git a/Profiler/Interactive/PhysicsEntitySnapshot.cs b/Profiler/Interactive/PhysicsEntitySnapshot.cs index cd8f3ba..5e15468 100644 --- a/Profiler/Interactive/PhysicsEntitySnapshot.cs +++ b/Profiler/Interactive/PhysicsEntitySnapshot.cs @@ -1,7 +1,5 @@ using Utils.General; using Sandbox.Game.Entities; -using Sandbox.Game.Entities.Cube; -using Sandbox.Game.Entities.EnvironmentItems; using Sandbox.Game.World; using VRage.Game.Entity; using VRage.Game.ModAPI; diff --git a/Profiler/Profiler.csproj b/Profiler/Profiler.csproj index cd86c96..4ec51b8 100644 --- a/Profiler/Profiler.csproj +++ b/Profiler/Profiler.csproj @@ -32,6 +32,14 @@ false + + ..\GameBinaries\Newtonsoft.Json.dll + False + + + ..\TorchBinaries\NLog.dll + False + @@ -46,14 +54,6 @@ - - $(SolutionDir)\TorchBinaries\Newtonsoft.Json.dll - False - - - $(SolutionDir)\TorchBinaries\Nlog.dll - False - $(SolutionDir)\GameBinaries\Sandbox.Common.dll False @@ -198,7 +198,6 @@ - @@ -220,13 +219,23 @@ - - - + + + + + + + + + + + + + diff --git a/Profiler/ProfilerCommands.cs b/Profiler/ProfilerCommands.cs index e8ce177..f82a9f5 100644 --- a/Profiler/ProfilerCommands.cs +++ b/Profiler/ProfilerCommands.cs @@ -22,6 +22,7 @@ using VRage.ModAPI; using Utils.Torch; using TaskUtils = Utils.General.TaskUtils; +// ReSharper disable InconsistentNaming namespace Profiler { @@ -74,6 +75,351 @@ public void Sim() }); } + [Command("diagnose", "Runs a comprehensive performance diagnostic across all subsystems")] + [Permission(MyPromoteLevel.Moderator)] + public void Diagnose() + { + Log.Info("Profile Diagnose Requested"); + this.CatchAndReportAsync(async () => + { + _args = new RequestParamParser(Context.Player, Context.Args); + var discordDisplay = Context.Player is null; + + Context.Respond($"Running performance diagnostic, result in {_args.Seconds}s..."); + + var gameLoop = new GameLoopProfiler(); + var grids = new GridProfiler(GameEntityMask.Empty); + var blockTypes = new BlockTypeProfiler(GameEntityMask.Empty); + var players = new PlayerProfiler(GameEntityMask.Empty); + var factions = new FactionProfiler(GameEntityMask.Empty); + var physics = new PhysicsProfiler(); + var session = new SessionComponentsProfiler(); + + using (ProfilerResultQueue.Profile(gameLoop)) + using (ProfilerResultQueue.Profile(grids)) + using (ProfilerResultQueue.Profile(blockTypes)) + using (ProfilerResultQueue.Profile(players)) + using (ProfilerResultQueue.Profile(factions)) + using (ProfilerResultQueue.Profile(physics)) + using (ProfilerResultQueue.Profile(session)) + { + gameLoop.MarkStart(); + grids.MarkStart(); + blockTypes.MarkStart(); + players.MarkStart(); + factions.MarkStart(); + physics.MarkStart(); + session.MarkStart(); + + await Task.Delay(TimeSpan.FromSeconds(_args.Seconds)); + + gameLoop.MarkEnd(); + grids.MarkEnd(); + blockTypes.MarkEnd(); + players.MarkEnd(); + factions.MarkEnd(); + physics.MarkEnd(); + session.MarkEnd(); + } + + var glResult = gameLoop.GetResult(); + var gridResult = grids.GetResult(); + var btResult = blockTypes.GetResult(); + var playerResult = players.GetResult(); + var factionResult = factions.GetResult(); + var physResult = physics.GetResult(); + var sessionResult = session.GetResult(); + + gameLoop.Dispose(); + grids.Dispose(); + blockTypes.Dispose(); + players.Dispose(); + factions.Dispose(); + physics.Dispose(); + session.Dispose(); + + // gather cluster grid details on game thread + var topClusters = physResult.GetTopEntities(3).ToArray(); + var clusterGrids = new List<(int Index, string Header, (string Name, int Blocks, double MsPerFrame)[] Grids)>(); + + if (topClusters.Length > 0) + { + try + { + await VRageUtils.MoveToGameLoop(); + + foreach (var (world, entry, ci) in topClusters.Select((kv, i) => (kv.Key, kv.Entity, i))) + { + var entities = world.GetEntities().OfType().ToArray(); + var gridCount = entities.Length; + var (size, _) = VRageUtils.GetBound(entities.Select(e => e.PositionComp.GetPosition())); + var sizeKm = size / 1000.0; + var msPerFrame = entry.MainThreadTime / physResult.TotalFrameCount; + + var gridInfos = new List<(string Name, int Blocks, double MsPerFrame)>(); + foreach (var grid in entities) + { + if (gridResult.TryGet(grid, out var ge)) + { + var ms = ge.MainThreadTime / gridResult.TotalFrameCount; + gridInfos.Add((grid.DisplayName, grid.BlocksCount, ms)); + } + } + + var topGrids = gridInfos + .OrderByDescending(x => x.MsPerFrame) + .Take(3) + .ToArray(); + + var header = $"[{ci}] {gridCount} grids, {sizeKm:0.0}km \u2014 {msPerFrame:0.00}ms/f"; + clusterGrids.Add((ci, header, topGrids)); + } + } + finally + { + await TaskUtils.MoveToThreadPool(); + } + } + + // player/faction grid counts (game thread, Discord only) + var playerGridCounts = new Dictionary(); + var factionGridCounts = new Dictionary(); + + if (discordDisplay) + { + try + { + await VRageUtils.MoveToGameLoop(); + + foreach (var group in MyCubeGridGroups.Static.Logical.Groups) + foreach (var node in group.Nodes) + { + var grid = node.NodeData; + foreach (var ownerId in grid.BigOwners) + { + playerGridCounts.TryGetValue(ownerId, out var pc); + playerGridCounts[ownerId] = pc + 1; + + var f = MySession.Static.Factions.TryGetPlayerFaction(ownerId); + if (f != null) + { + factionGridCounts.TryGetValue(f.FactionId, out var fc); + factionGridCounts[f.FactionId] = fc + 1; + } + } + } + } + finally + { + await TaskUtils.MoveToThreadPool(); + } + } + + // ---------------------------------------------------------------- + // build output + // ---------------------------------------------------------------- + var sb = new StringBuilder(); + + if (discordDisplay) + { + var discordTop = Math.Min(_args.Top, 5); + sb.AppendLine($"**Profiler Diagnose** ({_args.Seconds}s, {glResult.TotalFrameCount} fr)"); + + // frame breakdown (compact single line) + var physTotalMs = physResult.GetTopEntities().Sum(kv => kv.Entity.MainThreadTime) / physResult.TotalFrameCount; + + var frameItems = new (string Label, double Ms)[] + { + ("Upd", GetCategoryMs(glResult, ProfilerCategory.Update)), + ("Phys", physTotalMs), + ("Net", GetCategoryMs(glResult, ProfilerCategory.UpdateNetwork)), + ("Rep", GetCategoryMs(glResult, ProfilerCategory.UpdateReplication)), + ("Ses", GetCategoryMs(glResult, ProfilerCategory.UpdateSessionComponents)), + ("GPS", GetCategoryMs(glResult, ProfilerCategory.UpdateGps)), + ("PWait", GetCategoryMs(glResult, ProfilerCategory.UpdateParallelWait)), + ("Lock", GetCategoryMs(glResult, ProfilerCategory.Lock)), + }; + + var totalShown = frameItems.Sum(x => x.Ms); + var frameParts = frameItems + .Where(x => x.Ms > 0) + .Select(x => + { + var pct = totalShown > 0 ? x.Ms / totalShown * 100 : 0; + return $"{x.Label}: {x.Ms:0.0}ms ({pct:0.0}%)"; + }).ToList(); + + if (frameParts.Count > 0) + { + sb.Append("**Frame** "); + sb.AppendLine(string.Join(" | ", frameParts)); + } + + // top grids + var gridEntries = gridResult.GetTopEntities(discordTop).ToArray(); + if (gridEntries.Length > 0) + { + sb.AppendLine("**Top Grids**"); + foreach (var (grid, entry) in gridEntries) + { + var ms = entry.MainThreadTime / gridResult.TotalFrameCount; + sb.AppendLine($"> {grid.DisplayName} \u2014 {ms:0.00}ms/f, {grid.BlocksCount} blk"); + } + } + + // top block types + var btEntries = btResult.GetTopEntities(discordTop).ToArray(); + if (btEntries.Length > 0) + { + sb.AppendLine("**Top Block Types**"); + foreach (var (type, entry) in btEntries) + { + var ms = entry.MainThreadTime / btResult.TotalFrameCount; + sb.AppendLine($"> {BlockTypeToString(type)} \u2014 {ms:0.00}ms/f"); + } + } + + // top players + var playerEntries = playerResult.GetTopEntities(discordTop).ToArray(); + if (playerEntries.Length > 0) + { + sb.AppendLine("**Top Players**"); + foreach (var (identity, entry) in playerEntries) + { + var ms = entry.MainThreadTime / playerResult.TotalFrameCount; + var gc = playerGridCounts.TryGetValue(identity.IdentityId, out var c) ? c : 0; + sb.AppendLine($"> {identity.DisplayName} \u2014 {ms:0.00}ms/f, {gc} grids"); + } + } + + // top factions + var factionEntries = factionResult.GetTopEntities(discordTop).ToArray(); + if (factionEntries.Length > 0) + { + sb.AppendLine("**Top Factions**"); + foreach (var (faction, entry) in factionEntries) + { + var ms = entry.MainThreadTime / factionResult.TotalFrameCount; + var gc = factionGridCounts.TryGetValue(faction.FactionId, out var c) ? c : 0; + sb.AppendLine($"> [{faction.Tag}] \u2014 {ms:0.00}ms/f, {gc} grids"); + } + } + + // physics clusters + if (clusterGrids.Count > 0) + { + sb.AppendLine("**Top Physics Clusters**"); + foreach (var (_, header, clusterGridList) in clusterGrids) + { + sb.AppendLine($"> {header}"); + foreach (var (name, blocks, ms) in clusterGridList) + { + sb.AppendLine($"> \u2014 {name}, {ms:0.00}ms/f, {blocks} blk"); + } + } + } + + // session components + var sessionEntries = sessionResult.GetTopEntities(discordTop).ToArray(); + if (sessionEntries.Length > 0) + { + sb.AppendLine("**Top Session Components**"); + foreach (var (comp, entry) in sessionEntries) + { + var ms = entry.MainThreadTime / sessionResult.TotalFrameCount; + sb.AppendLine($"> {comp.GetType().Name} \u2014 {ms:0.00}ms/f"); + } + } + } + else + { + sb.AppendLine($"Profiler Diagnose ({_args.Seconds}s, {glResult.TotalFrameCount} fr)"); + + // frame breakdown + var physTotalMs = physResult.GetTopEntities().Sum(kv => kv.Entity.MainThreadTime) / physResult.TotalFrameCount; + + var frameItems = new (string Label, double Ms)[] + { + ("Upd", GetCategoryMs(glResult, ProfilerCategory.Update)), + ("Phys", physTotalMs), + ("Net", GetCategoryMs(glResult, ProfilerCategory.UpdateNetwork)), + ("Rep", GetCategoryMs(glResult, ProfilerCategory.UpdateReplication)), + ("Ses", GetCategoryMs(glResult, ProfilerCategory.UpdateSessionComponents)), + ("GPS", GetCategoryMs(glResult, ProfilerCategory.UpdateGps)), + ("Lock", GetCategoryMs(glResult, ProfilerCategory.Lock)), + }; + + var totalShown = frameItems.Sum(x => x.Ms); + sb.Append("-- Frame -- "); + var frameParts = new List(); + foreach (var (label, ms) in frameItems.Where(x => x.Ms > 0)) + { + var pct = totalShown > 0 ? ms / totalShown * 100 : 0; + frameParts.Add($"{label}:{ms:0.0}ms({pct:0}%)"); + } + sb.AppendLine(string.Join(", ", frameParts)); + + // top grids + sb.AppendLine("-- Top Grids --"); + foreach (var (grid, entry) in gridResult.GetTopEntities(_args.Top)) + { + var ms = entry.MainThreadTime / gridResult.TotalFrameCount; + sb.AppendLine($"\"{grid.DisplayName}\": {ms:0.00}ms/f, {grid.BlocksCount} blk"); + } + + // top block types + sb.AppendLine("-- Top Block Types --"); + foreach (var (type, entry) in btResult.GetTopEntities(_args.Top)) + { + var ms = entry.MainThreadTime / btResult.TotalFrameCount; + sb.AppendLine($"{BlockTypeToString(type)}: {ms:0.00}ms/f"); + } + + // top players + sb.AppendLine("-- Top Players --"); + foreach (var (identity, entry) in playerResult.GetTopEntities(_args.Top)) + { + var ms = entry.MainThreadTime / playerResult.TotalFrameCount; + sb.AppendLine($"{identity.DisplayName}: {ms:0.00}ms/f"); + } + + // top factions + sb.AppendLine("-- Top Factions --"); + foreach (var (faction, entry) in factionResult.GetTopEntities(_args.Top)) + { + var ms = entry.MainThreadTime / factionResult.TotalFrameCount; + sb.AppendLine($"[{faction.Tag}]: {ms:0.00}ms/f"); + } + + // physics clusters + if (clusterGrids.Count > 0) + { + sb.AppendLine("-- Top Physics Clusters --"); + foreach (var (_, header, clusterGridList) in clusterGrids) + { + var gridNames = string.Join(", ", clusterGridList.Select(g => $"\"{g.Name}\"")); + sb.AppendLine($"{header}: {gridNames}"); + } + } + + // session components + sb.AppendLine("-- Top Session Components --"); + foreach (var (comp, entry) in sessionResult.GetTopEntities(_args.Top)) + { + var ms = entry.MainThreadTime / sessionResult.TotalFrameCount; + sb.AppendLine($"{comp.GetType().Name}: {ms:0.00}ms/f"); + } + } + + Context.Respond(sb.ToString()); + }); + } + + static double GetCategoryMs(BaseProfilerResult result, ProfilerCategory category) + { + return result.TryGet(category, out var e) ? e.MainThreadTime / result.TotalFrameCount : 0; + } + [Command("frames", "Profiles game frames", HelpText)] [Permission(MyPromoteLevel.Moderator)] public void ProfileFrames() @@ -82,7 +428,7 @@ public void ProfileFrames() { _args = new RequestParamParser(Context.Player, Context.Args); - using (var profiler = new GameLoopProfiler()) + using var profiler = new GameLoopProfiler(); using (ProfilerResultQueue.Profile(profiler)) { Context.Respond($"Started profiling frames, result in {_args.Seconds}s"); @@ -125,7 +471,7 @@ public void ProfileBlockType() _args = new RequestParamParser(Context.Player, Context.Args); var mask = new GameEntityMask(_args.PlayerMask, _args.GridMask, _args.FactionMask); - using (var profiler = new BlockTypeProfiler(mask)) + using var profiler = new BlockTypeProfiler(mask); using (ProfilerResultQueue.Profile(profiler)) { Context.Respond($"Started profiling by block type, result in {_args.Seconds}s"); @@ -154,7 +500,7 @@ public void ProfileBlock() _args = new RequestParamParser(Context.Player, Context.Args); var mask = new GameEntityMask(_args.PlayerMask, _args.GridMask, _args.FactionMask); - using (var profiler = new BlockDefinitionProfiler(mask)) + using var profiler = new BlockDefinitionProfiler(mask); using (ProfilerResultQueue.Profile(profiler)) { Context.Respond($"Started profiling by block definition, result in {_args.Seconds}s"); @@ -192,7 +538,7 @@ BaseProfiler GetProfiler(GameEntityMask mask) { _args = new RequestParamParser(Context.Player, Context.Args); var mask = new GameEntityMask(_args.PlayerMask, _args.GridMask, _args.FactionMask); - using (var profiler = GetProfiler(mask)) + using var profiler = GetProfiler(mask); using (ProfilerResultQueue.Profile(profiler)) { Context.Respond($"Started profiling grids, result in {_args.Seconds}s"); @@ -259,7 +605,7 @@ public void ProfileFactions() _args = new RequestParamParser(Context.Player, Context.Args); var mask = new GameEntityMask(_args.PlayerMask, _args.GridMask, _args.FactionMask); - using (var profiler = new FactionProfiler(mask)) + using var profiler = new FactionProfiler(mask); using (ProfilerResultQueue.Profile(profiler)) { Context.Respond($"Started profiling factions, result in {_args.Seconds}s"); @@ -283,7 +629,7 @@ public void ProfilePlayers() _args = new RequestParamParser(Context.Player, Context.Args); var mask = new GameEntityMask(_args.PlayerMask, _args.GridMask, _args.FactionMask); - using (var profiler = new PlayerProfiler(mask)) + using var profiler = new PlayerProfiler(mask); using (ProfilerResultQueue.Profile(profiler)) { Context.Respond($"Started profiling players, result in {_args.Seconds}s"); @@ -307,7 +653,7 @@ public void ProfileScripts() _args = new RequestParamParser(Context.Player, Context.Args); var mask = new GameEntityMask(_args.PlayerMask, _args.GridMask, _args.FactionMask); - using (var profiler = new UserScriptProfiler(mask)) + using var profiler = new UserScriptProfiler(mask); using (ProfilerResultQueue.Profile(profiler)) { Context.Respond($"Started profiling scripts, result in {_args.Seconds}s"); @@ -336,7 +682,7 @@ public void ProfileSession() this.CatchAndReportAsync(async () => { _args = new RequestParamParser(Context.Player, Context.Args); - using (var profiler = new SessionComponentsProfiler()) + using var profiler = new SessionComponentsProfiler(); using (ProfilerResultQueue.Profile(profiler)) { Context.Respond($"Started profiling sessions, result in {_args.Seconds}s"); @@ -358,7 +704,7 @@ public void ProfileEntityTypes() this.CatchAndReportAsync(async () => { _args = new RequestParamParser(Context.Player, Context.Args); - using (var profiler = new EntityTypeProfiler()) + using var profiler = new EntityTypeProfiler(); using (ProfilerResultQueue.Profile(profiler)) { Context.Respond($"Started profiling entity types, result in {_args.Seconds}s"); @@ -414,7 +760,7 @@ public void ProfilePhysics() return; } - using (var profiler = new PhysicsProfiler()) + using var profiler = new PhysicsProfiler(); using (ProfilerResultQueue.Profile(profiler)) { Log.Warn("Physics profiling needs to sync all threads! This may cause performance impact."); diff --git a/Profiler/packages.config b/Profiler/packages.config deleted file mode 100644 index a6bdb97..0000000 --- a/Profiler/packages.config +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/manifest.xml b/manifest.xml index 04f7b18..93d4d3c 100644 --- a/manifest.xml +++ b/manifest.xml @@ -1,7 +1,7 @@ Profiler - da82de0f-9d2f-4571-af1c-88c7921bc063 - TorchAPI/Profiler - ${VERSION} + daa4de0f-9d2f-4571-af1c-88c7921bc063 + + SenX \ No newline at end of file