这几天做了一个并行运行的例子,但是发现运行之后,并行的效率很差,觉得应该是自己的代码有问题,但是又不知道怎么解决
请教各位大神,代码奉上
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 }
下面是执行后的结果
求救~
下面是电脑的配置,不知道会不会影响代码的性能
这样写:
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); } );
呃,没看懂。
不知道能否加一些注释 。
我现在想实现的功能是这样的,我需要分别向多个接口获取数据,这几个接口的返回值、参数列表都是一样的,就像我写的例子一样。所以,我想用并行运行的方式来读取这些数据,从而提高效率。望大神能详细解答一下。拜谢~
@取消操作: 这代码很简单啊,
将 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: 大哥,这个listLocal是什么啊?
是() => new List<int>()呢?
还是o?
@Eysa: 都是
原因只有1个
你的电脑配置太差了.并行运算本来就给超多核心的系统设计.
最常用的是GPU并行运算.因为CPU的核心数量没办法很多.
您好,我修改了一下问题,把电脑的配置发上来了。希望能详细指点一下~
@取消操作: 工作站都一样的.并行运算必须是在特定的环境下才行的.你I5 4核最多4个线程并行运算.
这种程度的并行运算你直接开几个线程就能达到了.
真想弄这些东西,去了解下怎么用GPU做并行运算吧,大几千的显卡应该就能有效果