跳转到内容
主菜单
主菜单
移至侧栏
隐藏
导航
首页
最近更改
随机页面
MediaWiki帮助
代码酷
搜索
搜索
中文(中国大陆)
外观
创建账号
登录
个人工具
创建账号
登录
未登录编辑者的页面
了解详情
贡献
讨论
编辑“︁
C Sharp 数据并行
”︁(章节)
页面
讨论
大陆简体
阅读
编辑
编辑源代码
查看历史
工具
工具
移至侧栏
隐藏
操作
阅读
编辑
编辑源代码
查看历史
常规
链入页面
相关更改
特殊页面
页面信息
外观
移至侧栏
隐藏
您的更改会在有权核准的用户核准后向读者展示。
警告:
您没有登录。如果您进行任何编辑,您的IP地址会公开展示。如果您
登录
或
创建账号
,您的编辑会以您的用户名署名,此外还有其他益处。
反垃圾检查。
不要
加入这个!
= C#数据并行 = == 介绍 == '''数据并行'''是并行编程的一种范式,指对数据集中的每个元素独立执行相同的操作。在C#中,数据并行主要通过<code>System.Threading.Tasks.Parallel</code>类和PLINQ(Parallel LINQ)实现。它适用于计算密集型任务,能够显著提高多核CPU的利用率。 数据并行的核心特点是: * 将数据集分割为多个独立分区 * 每个分区由不同的线程处理 * 最终合并处理结果 与任务并行(处理不同任务)不同,数据并行专注于对同一操作应用到大容量数据上。 == Parallel.For 和 Parallel.ForEach == C#提供了两种主要的数据并行结构: === Parallel.For === 用于并行执行for循环迭代,语法类似常规for循环: <syntaxhighlight lang="csharp"> using System; using System.Threading.Tasks; class Program { static void Main() { int[] data = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; Parallel.For(0, data.Length, i => { data[i] = data[i] * 2; Console.WriteLine($"Processing index {i} on thread {Task.CurrentId}"); }); Console.WriteLine("Result:"); foreach (var item in data) { Console.Write(item + " "); } } } </syntaxhighlight> '''输出示例'''(顺序可能不同): Processing index 2 on thread 1 Processing index 0 on thread 3 Processing index 5 on thread 2 Processing index 8 on thread 4 Processing index 1 on thread 5 Processing index 6 on thread 6 Processing index 3 on thread 7 Processing index 7 on thread 8 Processing index 4 on thread 9 Processing index 9 on thread 10 Result: 2 4 6 8 10 12 14 16 18 20 === Parallel.ForEach === 用于并行处理集合中的每个元素: <syntaxhighlight lang="csharp"> List<string> urls = new List<string> { "https://example.com/page1", "https://example.com/page2", // ...更多URL }; Parallel.ForEach(urls, url => { DownloadData(url); // 假设的下载方法 }); </syntaxhighlight> == 并行选项 == 可以通过<code>ParallelOptions</code>配置并行行为: <syntaxhighlight lang="csharp"> var options = new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount / 2, // 使用一半CPU核心 CancellationToken = cancellationToken }; Parallel.For(0, 100, options, i => { // 计算密集型工作 }); </syntaxhighlight> == PLINQ (Parallel LINQ) == PLINQ将LINQ查询并行化,只需添加<code>.AsParallel()</code>: <syntaxhighlight lang="csharp"> var source = Enumerable.Range(1, 10000); // 并行查询 var evenNumbers = source.AsParallel() .Where(x => x % 2 == 0) .Select(x => Math.Pow(x, 2)) .ToList(); </syntaxhighlight> == 线程安全注意事项 == 数据并行需要特别注意共享数据的访问: <syntaxhighlight lang="csharp"> int sum = 0; Parallel.For(0, 1000, i => { Interlocked.Add(ref sum, i); // 线程安全操作 // 等同于 lock 保护的 sum += i }); </syntaxhighlight> == 性能考量 == 数据并行并不总是更快,需要考虑: * '''开销''':并行化本身有开销,小数据集可能得不偿失 * '''内存局部性''':连续内存访问通常更快 * '''负载均衡''':确保工作均匀分配 <mermaid> graph TD A[开始并行操作] --> B{数据集大小>阈值?} B -->|是| C[分割数据集] B -->|否| D[顺序处理] C --> E[并行处理分区] E --> F[合并结果] F --> G[结束] D --> G </mermaid> == 实际应用案例 == '''图像处理'''是数据并行的典型应用。例如并行应用滤镜: <syntaxhighlight lang="csharp"> void ApplyFilterParallel(byte[] pixels, Func<byte, byte> filter) { Parallel.For(0, pixels.Length, i => { pixels[i] = filter(pixels[i]); }); } </syntaxhighlight> '''科学计算'''中矩阵运算也常使用数据并行: <math> \begin{pmatrix} a_{11} & \cdots & a_{1n} \\ \vdots & \ddots & \vdots \\ a_{m1} & \cdots & a_{mn} \end{pmatrix} + \begin{pmatrix} b_{11} & \cdots & b_{1n} \\ \vdots & \ddots & \vdots \\ b_{m1} & \cdots & b_{mn} \end{pmatrix} = \begin{pmatrix} a_{11}+b_{11} & \cdots & a_{1n}+b_{1n} \\ \vdots & \ddots & \vdots \\ a_{m1}+b_{m1} & \cdots & a_{mn}+b_{mn} \end{pmatrix} </math> 并行实现矩阵加法: <syntaxhighlight lang="csharp"> double[,] MatrixAddParallel(double[,] a, double[,] b) { int rows = a.GetLength(0); int cols = a.GetLength(1); double[,] result = new double[rows, cols]; Parallel.For(0, rows, i => { for (int j = 0; j < cols; j++) { result[i, j] = a[i, j] + b[i, j]; } }); return result; } </syntaxhighlight> == 最佳实践 == 1. '''测量性能''':始终比较并行和顺序版本的性能 2. '''避免过度并行化''':MaxDegreeOfParallelism通常设为CPU核心数 3. '''减少共享状态''':尽量使用局部变量 4. '''处理异常''':使用AggregateException处理并行操作中的异常 == 总结 == C#数据并行提供了强大的工具来处理计算密集型任务: * 使用Parallel.For/ForEach进行循环并行化 * 使用PLINQ并行化LINQ查询 * 注意线程安全和性能优化 * 适合大规模数据处理和计算密集型应用 正确使用时,数据并行可以显著提高应用程序性能,特别是在多核处理器上。 [[Category:编程语言]] [[Category:C Sharp]] [[Category:C Sharp 并发与多线程]]
摘要:
请注意,所有对代码酷的贡献均被视为依照知识共享署名-非商业性使用-相同方式共享发表(详情请见
代码酷:著作权
)。如果您不希望您的文字作品被随意编辑和分发传播,请不要在此提交。
您同时也向我们承诺,您提交的内容为您自己所创作,或是复制自公共领域或类似自由来源。
未经许可,请勿提交受著作权保护的作品!
取消
编辑帮助
(在新窗口中打开)