Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.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# 线程合并排序比串行实现慢_C#_Multithreading_Mergesort - Fatal编程技术网

C# 线程合并排序比串行实现慢

C# 线程合并排序比串行实现慢,c#,multithreading,mergesort,C#,Multithreading,Mergesort,对于学校来说,我们的任务是创建一个多线程应用程序。我们选择了合并排序的多线程实现 然而,我们无法使它比串行实现更快地工作 我已经尝试了以下方法: 具有无限线程的实现(代码示例1)(非常慢) 使用有限线程实现(代码示例2)(最多4个线程-仍然非常慢) 使用Parallel.Invoke实现(代码示例3)(更慢) 还具有并行合并功能的复杂实现(速度非常慢) 当我在VisualStudio(Instrumentation部分)中使用分析工具时,我发现调用的函数的计时,线程解决方案总是比串行实现慢得

对于学校来说,我们的任务是创建一个多线程应用程序。我们选择了合并排序的多线程实现

然而,我们无法使它比串行实现更快地工作

我已经尝试了以下方法:

  • 具有无限线程的实现(代码示例1)(非常慢)
  • 使用有限线程实现(代码示例2)(最多4个线程-仍然非常慢)
  • 使用Parallel.Invoke实现(代码示例3)(更慢)
  • 还具有并行合并功能的复杂实现(速度非常慢)
当我在VisualStudio(Instrumentation部分)中使用分析工具时,我发现调用的函数的计时,线程解决方案总是比串行实现慢得多

我看不出有什么可能的原因

(例如:有5000000个数字要排序;串行实现:16.717,17;并行实现:20.259,97;结果只需一个额外线程)

我在我拥有的两台机器上进行了测试:

  • 英特尔酷睿2四核Q9450@2.66Ghz
  • 英特尔酷睿i7 Q720@1.60Ghz
我一辈子都想不出这是怎么可能的,这难道不应该加速这个过程吗

如果有人能帮我,我会非常高兴的

代码示例1:

ParallelMerge pMerge = new ParallelMerge(T, p1, q1 -1, p2, q2-1, A, p3);
Thread thread = new Thread(new ThreadStart(pMerge.parallel_merge));
thread.Start();

ParallelMerge pMerge2 = new ParallelMerge(T, q1 + 1, r1, q2, r2, A, q3 + 1);
pMerge2.parallel_merge();
thread.Join();
代码示例2:

if(depthRemaining > 0)
{
   ParallelMerge pMerge = new ParallelMerge(T, p1, q1 -1, p2, q2-1, A, p3);
   thread thread = new Thread(new ThreadStart(pMerge.parallel_merge));
   thread.Start();
   ParallelMerge pMerge2 = new ParallelMerge(T, q1 + 1, r1, q2, r2, A, q3 + 1);
   pMerge2.parallel_merge(); 
   thread.Join();
}
else
{
   ParallelMerge pMerge = new ParallelMerge(T, p1, q1 -1, p2, q2-1, A, p3);
   pMerge.parallel_merge(); 
   ParallelMerge pMerge2 = new ParallelMerge(T, q1 + 1, r1, q2, r2, A, q3 + 1);
   pMerge.parallel_merge(); 
}
代码示例3:

if (depthRemaining > 0)
{
   Parallel.Invoke(
      () => threaded_merge_sort(getallen, p, q, depthRemaining-1));

   threaded_merge_sort(getallen, q + 1, r, 0);
}
else
{
   threaded_merge_sort(getallen, p, q, 0);
   threaded_merge_sort(getallen, q+1, r, 0);
}

你用什么时间单位报到

启动新线程是一个“缓慢”的操作。使用多线程对非常短的列表进行排序/合并可能会稍微慢一点

如果你只是把数字列表的长度分成两半,程序运行得更快吗?如果不是这样的话,代码就无法扩展

在没有实际代码实现的情况下回答这个问题有点困难

似乎问题不在于代码,而在于VS的分析工具

-阿恩·克雷布特


使用TPL(Parallel.Invoke)或线程池。通常,排序问题的瓶颈是I/O操作,因此并行计算不会带来很大的性能改进。50000个数字并不多。持续的线程创建/连接意味着大量可避免的开销。如果你有一本教科书说,使用线程需要创建线程,然后加入()ing等待结果,那就烧掉它。看看@HenkHolterman建议的线程池/TPL。我用TPL进行了尝试,如例3所示。这并没有给我太多的慢速度。但它也不能提供加速。我还注意到我在数字上漏掉了几个零。它应该是5000000,现在编辑它。合并排序还可以更好地与子列表上的就地排序相结合,比如CPU一级缓存大小。产生一个线程来合并2个项目的子列表的想法是可怕的。计时单位是毫秒,我还注意到我遗漏了一些零。应该是5000000个数字。我在pastebin上发布了我的代码: