升级服务器后,Parallel.ForEach变慢

时间:2015-11-19 23:40:02

标签: c# performance parallel-processing parallel.foreach

我有每日进程在20个文件夹上运行,其中包含60k +文件。没有子文件夹,输入文件的大小只有几MB。对于每个文件夹,我读取文件,解析它并将一些数据写入一个单独的输出文件(即20个输出文件)。我最近升级了我们的服务器(更高的核心和更高的内存),并注意到性能急剧下降。我希望有人能指出我的问题。

以下是我的代码

int iFolderCount = 0;
DirectoryInfo oSourceFolder = new DirectoryInfo(sInputFolder);
DirectoryInfo[] oIdDirectoryList = oSourceFolder.GetDirectories().Where(Id => sFolderList.Contains(Id.Name.ToUpper())).ToArray<DirectoryInfo>();
Parallel.ForEach(oIdDirectoryList, new ParallelOptions { MaxDegreeOfParallelism =  Environment.ProcessorCount }, (oId, state) =>
{
     FileInfo[] sFileList = oId.GetFiles();
     RawCounter.GetOrAdd(oId.Name.ToUpper(), sFileList.Length);

     using (StreamWriter oHandoffWriter = new StreamWriter(new FileStream(string.Format("{0}{1}_{2}_{3}{4}", sOutputFolder, Day, sOutputFileName, Interlocked.Increment(ref iFolderCount), HANDOFF_FILE_EXTENSION),FileMode.Append,FileAccess.Write,FileShare.Write)))
     {
         int iFileCounter = 0;
         foreach (FileInfo oFileInfo in sFileList)
         {
             try
             {
                 ProcessFile(oFileInfo, oHandoffWriter);
                 iFileCounter++;
             }
             catch (Exception ex)
             {
                 oLog.Info("Failed to process file " + oFileInfo.Name);
                 oLog.Info(ex.Message);
                 oLog.Info(ex.StackTrace);
                 oLog.Info(ex.InnerException);
                 File.Copy(oFileInfo.FullName, sErrorFileFolderPath + oFileInfo.Name, true);
             }
         }
         ProcessedCounter.GetOrAdd(oId.Name.ToUpper(), iFileCounter);
    }
});

将流程移至新服务器后,我注意到性能急剧下降。我们从8核到36核,8GB RAM到128 GB RAM。

Server Configuration

我开始降低并行度,并注意到每次降低度并行度时,过程表现都更好。

MaxDegreeOfParallelism =  2

通过设置为2,我看到了更高的性能。我在这里错过了什么? MaxDegreeOfParallelism = Environment.ProcessorCount在运行Windows Server 2008,8核,8GB RAM的旧服务器上更快,而MaxDegreeOfParallelism = 2在新的Windows服务器2012,32核心,128 GB RAM上更快。

编辑:我同意该过程是IO密集型的。每日文件数量/大小变化不大。以下是旧服务器上进程的完整时间。

  • 截止日期为20151028.该过程耗时504.05125171分钟。
  • 截止日期为20151027.该过程耗时504.37106602分钟。
  • 截止日期为20151026.该过程耗时549.76132134分钟。
  • 在20151025日完成切换。该过程耗时541.97557402分钟。
  • 20151024日完成了交接。该过程耗时567.14474476分钟。
  • 20151023日完成了交接。该过程耗时513.51368027分钟。
  • 2015-1022日完成了交接。该过程耗时595.21733215分钟。

在我使用 Environment.ProcessorCount 时在新服务器上   - 20151118日完成交接。该过程耗时 712.05125171 分钟。

在我使用 2 作为并行度的新服务器上   - 20151118日完成切换。该过程耗时 89.61782427 分钟。

我会做更多的运行并更新这个问题。

1 个答案:

答案 0 :(得分:4)

处理既不是CPU也不是内存绑定,因此新服务器根本没有帮助。它似乎IO约束。 IO硬件是否改变了?并行性加IO可能很容易意味着性能降低,因为顺序IO可能会变成随机IO。

根据CPU核心数选择IO的DOP是错误的。最佳IO DOP与核心数无关。根据经验确定最佳DOP。