指定默认的 MaxDegreeOfParallelism 会导致并行循环更快 运行
Specifing default MaxDegreeOfParallelism cause the parallel loop to run faster
我正在使用 System.Threading.Tasks.Parallel.ForEach()。
出于某种原因,将 MaxDegreeOfParallelism 设置为“-1”甚至“50”,会导致循环 运行 更快(大约 15 秒并且是一致的)。
MaxDegreeOfParallelism 参数的默认值为 -1,将其设置为 50 或任何其他数字只会使其变慢。
可能是什么原因?
System.Collections.Concurrent.ConcurrentBag<FileDataInfo> filesData = new System.Collections.Concurrent.ConcurrentBag<FileDataInfo>();
System.Threading.Tasks.Parallel.ForEach(filesInfo,
new System.Threading.Tasks.ParallelOptions() { MaxDegreeOfParallelism = -1 },
info =>
{
if (!string.IsNullOrEmpty(info.FolderPath))
info.FolderPath = System.IO.Path.Combine(dataPathDirName, info.FolderPath);
else
info.FolderPath = dataPathDirName;
var storageHandler = FileStorageFactory.CreateStorageHander();
byte[] data = storageHandler.GetFileData(info.FilePath);
filesData.Add(new FileDataInfo() { Info = info, Data = data });
});
MaxDegreeOfParallelism
告诉 TPL 有多少东西可以同时 运行ning。这会在很多方面影响执行速度。通过将此值设置为较低的值,它允许任务 运行 自己 CPU/Core。这使事情 运行 更快,因为您获得了良好的并行性。如果您将此值设置得更高(或设置为 -1),那么您可以 运行 执行比 CPUs/Cores 更多的任务。当发生这种情况时,跨任务共享 CPU 所需的时间可能会花费大量时间并使操作看起来更慢。
一般经验法则:不要将并行度设置为高于系统中 cores/CPUs 的数量。
你的问题不是 CPU-bound,而是 I/O 的问题。现代驱动器可以利用 I/O 的大队列来更有效地执行它。通过使用 Parallel.ForEach
,您将填满此队列并使驱动器以最高效率运行。
虽然您可能注意到此处速度有所提高,但值得注意的是您正在创建大量线程来完成此操作。过多的线程几乎从来都不是一个好主意,因为它由于调度程序开销和缓存流失而变得非常低效。如果可能,我建议转换代码以使用异步和 TPL 数据流。这将使您可以使用单个线程来管理大量并行 I/O 请求。
我正在使用 System.Threading.Tasks.Parallel.ForEach()。 出于某种原因,将 MaxDegreeOfParallelism 设置为“-1”甚至“50”,会导致循环 运行 更快(大约 15 秒并且是一致的)。 MaxDegreeOfParallelism 参数的默认值为 -1,将其设置为 50 或任何其他数字只会使其变慢。 可能是什么原因?
System.Collections.Concurrent.ConcurrentBag<FileDataInfo> filesData = new System.Collections.Concurrent.ConcurrentBag<FileDataInfo>();
System.Threading.Tasks.Parallel.ForEach(filesInfo,
new System.Threading.Tasks.ParallelOptions() { MaxDegreeOfParallelism = -1 },
info =>
{
if (!string.IsNullOrEmpty(info.FolderPath))
info.FolderPath = System.IO.Path.Combine(dataPathDirName, info.FolderPath);
else
info.FolderPath = dataPathDirName;
var storageHandler = FileStorageFactory.CreateStorageHander();
byte[] data = storageHandler.GetFileData(info.FilePath);
filesData.Add(new FileDataInfo() { Info = info, Data = data });
});
MaxDegreeOfParallelism
告诉 TPL 有多少东西可以同时 运行ning。这会在很多方面影响执行速度。通过将此值设置为较低的值,它允许任务 运行 自己 CPU/Core。这使事情 运行 更快,因为您获得了良好的并行性。如果您将此值设置得更高(或设置为 -1),那么您可以 运行 执行比 CPUs/Cores 更多的任务。当发生这种情况时,跨任务共享 CPU 所需的时间可能会花费大量时间并使操作看起来更慢。
一般经验法则:不要将并行度设置为高于系统中 cores/CPUs 的数量。
你的问题不是 CPU-bound,而是 I/O 的问题。现代驱动器可以利用 I/O 的大队列来更有效地执行它。通过使用 Parallel.ForEach
,您将填满此队列并使驱动器以最高效率运行。
虽然您可能注意到此处速度有所提高,但值得注意的是您正在创建大量线程来完成此操作。过多的线程几乎从来都不是一个好主意,因为它由于调度程序开销和缓存流失而变得非常低效。如果可能,我建议转换代码以使用异步和 TPL 数据流。这将使您可以使用单个线程来管理大量并行 I/O 请求。