Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/263.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 指定默认MaxDegreeOfParallelism会使并行循环运行得更快_C#_Task Parallel Library_Parallel.foreach - Fatal编程技术网

C# 指定默认MaxDegreeOfParallelism会使并行循环运行得更快

C# 指定默认MaxDegreeOfParallelism会使并行循环运行得更快,c#,task-parallel-library,parallel.foreach,C#,Task Parallel Library,Parallel.foreach,我使用的是System.Threading.Tasks.Parallel.ForEach()。 出于某种原因,将MaxDegreeOfParallelism设置为“-1”甚至“50”会导致循环运行得更快(大约15秒,并且是一致的)。 MaxDegreeOfParallelism参数的默认值为-1,将其设置为50或任何其他数字只会使其变慢。 原因可能是什么 System.Collections.Concurrent.ConcurrentBag<FileDataInfo> filesDa

我使用的是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 });
        });
System.Collections.Concurrent.ConcurrentBag filesData=new System.Collections.ConcurrentBag();
System.Threading.Tasks.Parallel.ForEach(filesInfo,
新的System.Threading.Tasks.ParallelOptions(){MaxDegreeOfParallelism=-1},
信息=>
{
如果(!string.IsNullOrEmpty(info.FolderPath))
info.FolderPath=System.IO.Path.Combine(dataPathDirName,info.FolderPath);
其他的
info.FolderPath=dataPathDirName;
var storageHandler=FileStorageFactory.CreateStorageHander();
字节[]数据=storageHandler.GetFileData(info.FilePath);
添加(新的FileDataInfo(){Info=Info,Data=Data});
});

MaxDegreeOfParallelism
告诉TPL可以同时运行多少个东西。这会在许多方面影响执行速度。通过将此值设置为较低的值,它允许任务在自己的CPU/内核上运行。这使事情运行得更快,因为您获得了良好的并行性。如果将该值设置得更高(或设置为-1),则可以运行比CPU/内核更多的任务。当这种情况发生时,跨任务共享CPU所需的时间可能会占用大量的时间,并使操作看起来更慢


一般经验法则:不要将并行度设置为高于系统中的内核/CPU数量。

MaxDegreeOfParallelism
告诉TPL同时可以运行多少东西。这会在许多方面影响执行速度。通过将此值设置为较低的值,它允许任务在自己的CPU/内核上运行。这使事情运行得更快,因为您获得了良好的并行性。如果将该值设置得更高(或设置为-1),则可以运行比CPU/内核更多的任务。当这种情况发生时,跨任务共享CPU所需的时间可能会占用大量的时间,并使操作看起来更慢


一般经验法则:不要将并行度设置为高于系统中的内核/CPU数量。

您的问题不是CPU限制,而是I/O限制。现代驱动器可以利用大量I/O队列来更高效地执行。通过使用
Parallel.ForEach
,您将填充此队列,并使驱动器以最大效率运行


虽然您可能会注意到这里的加速,但值得注意的是,您正在创建大量线程来实现这一点。过多的线程几乎从来都不是一个好主意,因为由于调度程序开销和缓存搅动,它变得非常低效。如果可能,我建议将代码转换为使用异步和TPL数据流。这将允许您使用单个线程来管理大量并行I/O请求。

您的问题不受CPU限制,而是受I/O限制。现代驱动器可以利用大量I/O队列来更高效地执行。通过使用
Parallel.ForEach
,您将填充此队列,并使驱动器以最大效率运行


虽然您可能会注意到这里的加速,但值得注意的是,您正在创建大量线程来实现这一点。过多的线程几乎从来都不是一个好主意,因为由于调度程序开销和缓存搅动,它变得非常低效。如果可能,我建议将代码转换为使用异步和TPL数据流。这将允许您使用单个线程来管理大量并行I/O请求。

您的最后一句话与第一句话相反。您可以重新表述您的问题吗?在一句话中你说它快,下一句你说它慢。你在问什么?我看你的代码中没有昂贵的任务。并行化任务只适用于昂贵的任务,如果您尝试并行化许多小任务,可能会对您的性能产生负面影响(或者您可能会得到一点提升,这不值得您的代码引入复杂性)。@M.kazem Akhgary GetFileData()是一项昂贵的任务
GetFileData
听起来像是一项I/O主导的任务<代码>并行。ForEach不是一个很好的选择-它是为CPU主导的任务设计的,理想情况下完全没有I/O。你的最后一句话与第一句相反。你能重新表述你的问题吗?在一句话中你说它快,下一句你说它慢。你在问什么?我看你的代码中没有昂贵的任务。并行化任务只适用于昂贵的任务,如果您尝试并行化许多小任务,可能会对您的性能产生负面影响(或者您可能会得到一点提升,这不值得您的代码引入复杂性)。@M.kazem Akhgary GetFileData()是一项昂贵的任务
GetFileData
听起来像是一项I/O主导的任务<代码>并行。ForEach不是一个好的选择-它是为CPU主导的任务而设计的,理想情况下根本没有I/O。