首页 新闻 会员 周边

.net Parallel 并行运行的问题请教

0
悬赏园豆:20 [已解决问题] 解决于 2014-08-28 14:22

这几天做了一个并行运行的例子,但是发现运行之后,并行的效率很差,觉得应该是自己的代码有问题,但是又不知道怎么解决

 请教各位大神,代码奉上

 1 class Program
 2     {
 3         static void Main(string[] args)
 4         {
 5             Console.WriteLine("Parallel[{0}]",DateTime.Now);
 6             for (int i = 0; i < 9999; i++)
 7             {
 8                 var list = new BlockingCollection<int>();
 9                 Action[] a = new Action[] 
10                 {  
11                     ()=>{Add1(list);},
12                     ()=>{Add2(list);},
13                     ()=>{Add3(list);},
14                 };
15                 Parallel.Invoke(a);
16                 //Console.WriteLine(list.Count);
17                 //list.ToList().ForEach(m => Console.WriteLine(string.Format("{0}:{1}", i , m)));
18             }
19             Console.WriteLine("Parallel[{0}]", DateTime.Now);
20 
21             Console.WriteLine("Common[{0}]", DateTime.Now);
22             for (int i = 0; i < 9999; i++)
23             {
24                 List<int> arry = new List<int>();
25                 Add1(arry);
26                 Add2(arry);
27                 Add3(arry);
28                 //Console.WriteLine(arry.Count);
29             }
30             Console.WriteLine("Common[{0}]", DateTime.Now);
31             Console.Read();
32         }
33 
34         static void Add1(BlockingCollection<int> list)
35         {
36             for (int i = 0; i < 9999; i++)
37             {
38                  list.TryAdd(10000 + i);
39             }
40         }
41 
42         static void Add2(BlockingCollection<int> list)
43         {
44             for (int i = 0; i < 9999; i++)
45             {
46                 list.TryAdd(20000 + i);
47             }
48         }
49 
50         static void Add3(BlockingCollection<int> list)
51         {
52             for (int i = 0; i < 9999; i++)
53             {
54                 list.TryAdd(30000 + i);
55             }
56         }
57 
58 
59         static void Add1(List<int> list)
60         {
61             for (int i = 0; i < 9999; i++)
62             {
63                  list.Add(10000 + i);
64             }
65         }
66 
67         static void Add2(List<int> list)
68         {
69             for (int i = 0; i < 9999; i++)
70             {
71                 list.Add(20000 + i);
72             }
73         }
74 
75         static void Add3(List<int> list)
76         {
77             for (int i = 0; i < 9999; i++)
78             {
79                 list.Add(30000 + i);
80             }
81         }
82     }

下面是执行后的结果

求救~

下面是电脑的配置,不知道会不会影响代码的性能

取消操作的主页 取消操作 | 初学一级 | 园豆:186
提问于:2014-05-28 15:37
< >
分享
最佳答案
0

这样写:

            int[] numbers = new int[1000];
            List<int> listFinally = new List<int>();

            ParallelLoopResult loopResult = Parallel.ForEach(
                Partitioner.Create(numbers, true),
                () => new List<int>(),
               (number, state, i, listLocal) =>
               {
                   listLocal.Add(number);
                   return listLocal;
               },
                o =>
                {
                    lock(listFinally)
                        listFinally.AddRange(o);
                }
               );
收获园豆:20
Launcher | 高人七级 |园豆:45045 | 2014-05-28 16:31

呃,没看懂。

不知道能否加一些注释 。

我现在想实现的功能是这样的,我需要分别向多个接口获取数据,这几个接口的返回值、参数列表都是一样的,就像我写的例子一样。所以,我想用并行运行的方式来读取这些数据,从而提高效率。望大神能详细解答一下。拜谢~

取消操作 | 园豆:186 (初学一级) | 2014-05-28 18:21

@取消操作: 这代码很简单啊,

将 numbers 数组分成 N 个区(通常为逻辑处理器数):Partitioner.Create(numbers, true)

为每个分区创建一个用于保存结果的集合,返回值对应下面的 listLocal,没分区一个,不存在共享资源的问题 : () => new List<int>()

在每个分区上执行的方法:

(number, state, i, listLocal) =>
               {
                   listLocal.Add(number);
                   return listLocal;
               }

所有分区的操作完成后,合并所有分区的集合到最终结果:

o =>
{
  lock(listFinally)    // 各分区完成有先后,存在并发,对共享资源 listFinally 的访问需要同步
    listFinally.AddRange(o);  // AddRange 会比多次 Add 快,这也是这个示例虽然对并行算法不友好,但是却能通过并行算法来提高性能。
}

Launcher | 园豆:45045 (高人七级) | 2014-05-29 09:39

@Launcher: 大哥,这个listLocal是什么啊?

是() => new List<int>()呢?

还是o?

Eysa | 园豆:62 (初学一级) | 2014-11-05 08:20

@Eysa: 都是

Launcher | 园豆:45045 (高人七级) | 2014-11-05 09:15
其他回答(1)
0

原因只有1个

你的电脑配置太差了.并行运算本来就给超多核心的系统设计.

最常用的是GPU并行运算.因为CPU的核心数量没办法很多.

吴瑞祥 | 园豆:29449 (高人七级) | 2014-05-28 15:40

您好,我修改了一下问题,把电脑的配置发上来了。希望能详细指点一下~

支持(0) 反对(0) 取消操作 | 园豆:186 (初学一级) | 2014-05-28 16:12

@取消操作: 工作站都一样的.并行运算必须是在特定的环境下才行的.你I5  4核最多4个线程并行运算.

这种程度的并行运算你直接开几个线程就能达到了.

真想弄这些东西,去了解下怎么用GPU做并行运算吧,大几千的显卡应该就能有效果

支持(0) 反对(0) 吴瑞祥 | 园豆:29449 (高人七级) | 2014-05-28 17:57
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册