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