diff --git a/Wabbajack.Common/WorkQueue.cs b/Wabbajack.Common/WorkQueue.cs index e9df2a6c..ef1eb526 100644 --- a/Wabbajack.Common/WorkQueue.cs +++ b/Wabbajack.Common/WorkQueue.cs @@ -134,7 +134,7 @@ namespace Wabbajack.Common // Noticed that we may need to shut down, lock and check again using (await _lock.Wait()) { - // Check if another thread shut down before this one and got us in line + // Check if another thread shut down before this one and got us back to the desired amount already if (DesiredNumWorkers >= _tasks.Count) continue; Report("Shutting down", 0, false); diff --git a/Wabbajack.Lib/ABatchProcessor.cs b/Wabbajack.Lib/ABatchProcessor.cs index 222b2258..f872fc0d 100644 --- a/Wabbajack.Lib/ABatchProcessor.cs +++ b/Wabbajack.Lib/ABatchProcessor.cs @@ -70,6 +70,11 @@ namespace Wabbajack.Lib VFS = new Context(Queue) { UpdateTracker = UpdateTracker }; } + /// + /// Gets the recommended maximum number of threads that should be used for the current machine. + /// This will either run a heavy processing job to do the measurement in the current folder, or refer to caches. + /// + /// Recommended maximum number of threads to use public async Task RecommendQueueSize() { const ulong GB = (1024 * 1024 * 1024); @@ -83,6 +88,40 @@ namespace Wabbajack.Lib return result; } + /// + /// Gets the recommended maximum number of threads that should be used for the current machine. + /// This will either run a heavy processing job to do the measurement in the specified folder, or refer to caches. + /// + /// If the folder does not exist, it will be created, and not cleaned up afterwards. + /// + /// + /// Recommended maximum number of threads to use + public static async Task RecommendQueueSize(string folder) + { + if (!Directory.Exists(folder)) + Directory.CreateDirectory(folder); + + using (var queue = new WorkQueue()) + { + Utils.Log($"Benchmarking {folder}"); + var raw_speed = await Utils.TestDiskSpeed(queue, folder); + Utils.Log($"{raw_speed.ToFileSizeString()}/sec for {folder}"); + int speed = (int)(raw_speed / 1024 / 1024); + + // Less than 100MB/sec, stick with two threads. + return speed < 100 ? 2 : Math.Min(Environment.ProcessorCount, speed / 100 * 2); + } + } + + /// + /// Constructs an observable of the number of threads to be used + /// + /// Takes in a recommended amount (based off measuring the machine capabilities), and combines that with user preferences stored in subjects. + /// + /// As user preferences change, the number of threads gets recalculated in the resulting observable + /// + /// Maximum recommended number of threads + /// Observable of number of threads to use based off recommendations and user preferences public IObservable ConstructDynamicNumThreads(int recommendedCount) { return Observable.CombineLatest( @@ -108,23 +147,6 @@ namespace Wabbajack.Lib }); } - public static async Task RecommendQueueSize(string folder) - { - if (!Directory.Exists(folder)) - Directory.CreateDirectory(folder); - - using (var queue = new WorkQueue()) - { - Utils.Log($"Benchmarking {folder}"); - var raw_speed = await Utils.TestDiskSpeed(queue, folder); - Utils.Log($"{raw_speed.ToFileSizeString()}/sec for {folder}"); - int speed = (int)(raw_speed / 1024 / 1024); - - // Less than 100MB/sec, stick with two threads. - return speed < 100 ? 2 : Math.Min(Environment.ProcessorCount, speed / 100 * 2); - } - } - protected abstract Task _Begin(CancellationToken cancel); public Task Begin() {