【C#】并行编程实战:实现数据并行(4)

news2024/9/21 4:29:41

         本章继续学习实现数据并行,本文主要介绍并行循环中的线程存储。这也是本章节的最后一篇。

        本教程对应学习工程:魔术师Dix / HandsOnParallelProgramming · GitCode        


5、了解并行循环中的线程存储

        默认情况下,所有并行循环都可以访问全局变量。但是,访问全局变量是有同步开销的,因此,尽可能使用线程内局部变量是有意义的。在并行循环中,可以创建和使用线程局部变量(Thread Local Varable,也称为线程本地变量)或分区局部变量(Partition Local Variable,也称分区本地变量)。

5.1、线程局部变量(Thread Local Varable)

        这里用到了一个 Parallel.For 的一个重载:

Parallel.For 方法 (System.Threading.Tasks) | Microsoft Learn执行 for 循环,其中可能会并行运行迭代。 icon-default.png?t=N5K3https://learn.microsoft.com/zh-cn/dotnet/api/system.threading.tasks.parallel.for?view=netstandard-2.1#system-threading-tasks-parallel-for-1(system-int64-system-int64-system-threading-tasks-paralleloptions-system-func((-0))-system-func((system-int64-system-threading-tasks-parallelloopstate-0-0))-system-action((-0)))        示例代码如下:

        private void RunByThreadLocalVarable()
        {
            var options = new ParallelOptions { MaxDegreeOfParallelism = 3 };//最大并行度3
            Parallel.For(0, 11, options,//从0开始循环,循环11次(到10结束)
                () => 100,//第一次循环时的初始值
                (i, loop, ret) =>
                {
                    ret += i;
                    return ret;//返回给下一次循环的值
                }, TestFunction.OnTaskFinish);//最后运行完成的回调
        }

        迭代里面的方法很简单,就是单纯地累加。从0加到10,显然就是55。但是我们给每次循环的初始值是100,也就是每次迭代开始,就会从100开始计数。然后最大并行度为3,也就是最多会有 3 次线程并行。根据上述代码,我们人脑编译一下,运行结果应该是 100+100+100+55=355 (如果并行了3次)。

        跑一下代码:

         结果为 :134+100+121=355,与理论相同。

5.2、分区局部变量(Partition Local Variable)

        分区局部变量与线程局部变量类似,区别在于其可以用于分区,这次用到的重载是这个:

Parallel.ForEach 方法 (System.Threading.Tasks) | Microsoft Learn执行 foreach(在 Visual Basic 中为 For Each )操作,其中可能会并行运行迭代。 icon-default.png?t=N5K3https://learn.microsoft.com/zh-cn/dotnet/api/system.threading.tasks.parallel.foreach?view=netstandard-2.1#system-threading-tasks-parallel-foreach-2(system-collections-concurrent-partitioner((-0))-system-threading-tasks-paralleloptions-system-func((-1))-system-func((-0-system-threading-tasks-parallelloopstate-1-1))-system-action((-1)))        这次需要加一个 Partitioner 的测试代码:

using System.Collections.Concurrent;
using System.Collections.Generic;
using UnityEngine;

namespace HOPP.Ch03
{
    /// <summary>
    /// 测试用分区局部变量
    /// </summary>
    public class PartitionerTest : Partitioner<List<int>>
    {

        //这里共享一个列表,以观察线程竞争
        private List<int> L = new List<int>();

        public override bool SupportsDynamicPartitions => true;

        //这个方法在此示例中没有被调用过
        public override IList<IEnumerator<List<int>>> GetPartitions(int partitionCount)
        {
            Debug.Log($" GetPartitions {L.Count} | {partitionCount}");
            for (int i = 0; i < 10; i++)
                L.Add(i);
            return (IList<IEnumerator<List<int>>>)L;
        }

        //迭代:每次调用就添加一个值;
        public override IEnumerable<List<int>> GetDynamicPartitions()
        {
            Debug.Log($"GetDynamicPartitions Start: {L.Count}");
            for (int i = 0; i < 10; i++)
            {
                L.Add(i);
                Debug.Log("Add Value : " + i);
                //Debug.Log($" GetDynamicPartitions {L.Count} ");
                yield return L;
            }

            Debug.Log($" GetDynamicPartitions  Last: {L.Count} ");
            yield return L;
        }

    }
}

Partitioner表示将数据源拆分为多个分区的特定方式。 icon-default.png?t=N5K3https://learn.microsoft.com/zh-cn/dotnet/api/system.collections.concurrent.partitioner-1?view=netstandard-2.1        之后我们开始调用:

        private void RunByPartitionLocalVarable()
        {
            var partitioner = new PartitionerTest();
            var options = new ParallelOptions { MaxDegreeOfParallelism = 3 };//最大并行度3
            Parallel.ForEach(partitioner,
                options,
                () => 0,//第一次迭代时的初始值
                (L, loop, ret) =>
                {
                    //每次都将列表中的值汇总
                    ret = 0;
                    foreach (var item in L)
                        ret += item;
                    return ret;//返回给下一次循环的值
                }, TestFunction.OnTaskFinish);//最后运行完成的回调
        }

        可以想象的是,因为线程竞争,所以3次并行的结果都会有所差别,实际也是如此。我们直接看最后的结果打印:

         2个线程同步执行完成,打印出了结果105,最后一个线程结果135,最后一个完成。


本章总结

        本章详细介绍了使用任务并行库(TPL)实现数据并行的方式。

        这一章的实用性也很强了,而且已经开始涉及到数据的处理,但是这里还没有讲如何处理线程竞争的问题。不过通过这一章的学习,相信大家对多线程的运行模式已经有了更为深刻的理解。

        虽然本章提到了怎么分区,但是并没有很深入。要用好各种分区、局部变量策略,还需要继续深入学习。

         本教程对应学习工程:魔术师Dix / HandsOnParallelProgramming · GitCode        

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/714449.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

13.1 非线性变化的图像增强和补偿——滤波器对图像作增强提高视觉质量(matlab程序)

1.简述 图像的线性变换和非线性变换&#xff0c;逐像素运算就是对图像的没一个像素点的亮度值&#xff0c;通过一定的函数关系&#xff0c;转换到新的亮度值。这个转换可以由函数表示&#xff1a; s f ( r ) s f( r )sf(r) 其中r为原来的像素值&#xff0c;s为新的像素值&a…

关于visual studio 2010 及以上版本 引入boost库的最新解决方法

之前没有怎么用到boost库&#xff0c;出来实习需要去编译一些代码&#xff0c;需要引入boost第三方库&#xff0c;在这过程中&#xff0c;一直出现 LINK : fatal error LNK1104: 无法打开文件“libboost_filesystem-vc100-mt-gd-x3 错误&#xff0c; 但是也确实是跟其他教程学过…

BUUCTF [GXYCTF2019] CheckIn 1

BUUCTF:https://buuoj.cn/challenges 题目描述&#xff1a; 密文&#xff1a; dikqTCpfRjA8fUBIMD5GNDkwMjNARkUwI0BFTg解题思路&#xff1a; 1、观察密文&#xff0c;一眼Base64加密&#xff0c;使用在线工具Base64加解密&#xff0c;得到另一串密文。 v)*L*_F0<}H0>…

Apifox|API 文档和开发闭环初体验

Apifox是一款集文档、接口定义、数据模拟、自动化测试为一体的接口协作平台。 据功能介绍&#xff0c;基本总结Apifox Postman Swagger Mock JMeter 既然评的文章那么多&#xff0c;掀起了一阵子热度&#xff0c;究竟哪些功能&#xff1a; 用下来有哪些体会&#xff1a;…

Web3.0 应用开发:选择合适的框架和工具至关重要

随着 Web3.0 时代的到来&#xff0c;区块链技术的普及和应用让去中心化的应用开发变得更加可行。然而&#xff0c;要开发出高效、稳定和安全的 Web3.0 应用&#xff0c;选择合适的框架和工具至关重要。本文将介绍 Web3.0 应用开发的关键因素&#xff0c;帮助开发者做出明智的选…

【Vue+Django】Training Management Platform Axios并发请求 - 20230703

需求陈述 由于API是特定单位/特定类别/特定教学方式的数据&#xff0c;故汇总数据需要循环请求不同单位/不同类别/不同教学方式。 技术要点 1.axios并发请求 2.JS for循环 3.Vue数组中出现 ob :Observer无法取值问题的解决方法 4.将数据转化为数组 5.一次请求所有数据后&…

交安三类人员专职安全生产管理人员(c证)考试题库及答案(主观题)

本题库是根据最新考试大纲要求&#xff0c;结合近年来考试真题的重难点进行汇编整理组成的全真模拟试题&#xff0c;考生们可以进行专项训练&#xff0c;查漏补缺巩固知识点。本题库对热点考题和重难点题目都进行了仔细的整理和编辑&#xff0c;相信考生在经过了针对性的刷题练…

计算机由于找不到d3dx9_35.dll,无法启动软件游戏的三个修复方法

在打开游戏的时候&#xff0c;计算机提示由于找不到d3dx9_35.dll&#xff0c;无法正常启动运行。这个是为什么呢&#xff1f;d3dx9_35.dll是DirectX 9.0里面的一个动态连结库文件&#xff0c;它包含了Direct3D、DirectPlay几个组件的二进制文件&#xff0c;为软件提供了多媒体图…

Cisco Catalyst 8000 Series Edge Platforms, IOS XE Release Dublin-17.11.01a ED

Cisco Catalyst 8000 Series Edge Platforms, IOS XE Release Dublin-17.11.01a ED Cisco Catalyst 8000 边缘平台系列 请访问原文链接&#xff1a;https://sysin.org/blog/cisco-catalyst-8000/&#xff0c;查看最新版。原创作品&#xff0c;转载请保留出处。 作者主页&…

【Matlab】智能优化算法_多元宇宙优化算法MVO

【Matlab】智能优化算法_多元宇宙优化算法MVO 1.背景介绍2.数学模型3.文件结构4.详细代码及注释4.1 func_plot.m4.2 Get_Functions_details.m4.3 initialization.m4.4 main.m4.5 MVO.m4.6 RouletteWheelSelection.m 5.运行结果6.参考文献 1.背景介绍 大爆炸理论讨论了我们的宇宙…

基于CentOS7安装配置docker与docker-compose

Docker是基于Go语言实现的云开源项目。 Docker的主要目标是“Build&#xff0c;Ship and Run Any App,Anywhere”&#xff0c;也就是通过对应用组件的封装、分发、部署、运行等生命周期的管理&#xff0c;使用户的APP&#xff08;可以是一个WEB应用或数据库应用等等&#xff09…

解决方案︱视频孪生智慧场馆解决方案

一、方案概述 视频孪生场馆综合管理系统&#xff0c;是综合数字孪生、三维地理信息、视频监控等技术于一体的创新性综合管理平台。 平台基于三维地理&#xff08;3D GIS&#xff09;引擎&#xff0c;综合运用了人工智能、大数据、三维GIS、遥感、计算机图形学等新一代空间信息…

【PCL】(四)点云可视化

文章目录 可视化CloudViewer 可视化PCLVisualizer 可视化可视化单个云添加一些颜色RGB点云指定颜色 法线和其他信息绘制形状多个窗口交互自定义 可视化 CloudViewer 可视化 将【PCL】&#xff08;一&#xff09;PCL基本数据结构PointCloud与原生文件格式PCD末尾的数据保存到m…

blender 之点云渲染(论文渲图)

blender 之点云渲染&#xff08;论文渲图&#xff09; 一、导入点云1.新建2.导入点云3.位置移动&放大缩小 二、Geometry Nodes实体化点云1.新建节点2.实体化 三、给实体化点云添加材质四、设置渲染引擎更换为Cycles。 五、对准视角1.新建一个球2.创建相机视角跟踪3.将uv球挪…

阿里巴巴java开发手册

前言 以下内容整理来自阿里巴巴java开发手册&#xff0c;方便在线查看。 一、编程规约 1.1 命名风格 【强制】代码中的命名均不能以下划线或美元符号开始&#xff0c;也不能以下划线或美元符号结束。 反例&#xff1a;_name / __name / O b j e c t / n a m e / n a m e O…

【论文阅读笔记】Analyzing Federated Learning through an Adversarial Lens

个人阅读笔记&#xff0c;如有错误欢迎指出 ICML 2019 [1811.12470] Analyzing Federated Learning through an Adversarial Lens (arxiv.org) 问题&#xff1a; 传统模型攻击容易被服务器通过精度检测以及权重分析检测出来&#xff0c;本文意在找到一种投毒方法绕过服…

Yolov8优化:最新移动端高效网络架构 CloFormer: 注意力机制与卷积的完美融合 | 清华团队2023 即插即用系列

💡💡💡本文属于原创独家改进:引入CloFormer 中的 AttnConv,上下文感知权重使得模型能够更好地适应输入内容。相比于局部自注意力机制,引入共享权重使得模型能够更好地处理高频信息,从而提高性能。 注意力机制与卷积的完美融合 AttnConv | 亲测在多个数据集能够实现…

React 编译之后修改服务地址

编写react 的项目中&#xff0c;我们要调用后台服务的地址&#xff0c;当前后台服务器的地址在是写Axios相关的js文件中&#xff0c; 但是项目我们在yarn build之后&#xff0c;变成了这样&#xff1a; 我们根本没有办法修改相关冯server_address,这样就产生了很大的局限性&…

24JS15——DOM

文章目录 一、DOM简介1、什么是DOM2、DOM树 二、获取元素1、如何获取页面元素2、根据id获取3、根据标签名获取4、通过HTML5新增的方法获取5、获取特殊元素body html 三、事件基础1、事件概述2、事件三要素3、执行事件的步骤 四、操作元素1、改变元素内容2、常用元素的属性操作3…

2017计算机学科夏令营上机考试

目录 A:判决素数个数【水题】 B:编码字符串(string)【水题】 C:岛屿周长(matrix)【深搜或者找规律】 D:Safecracker【深搜或者暴力不水】 E:怪盗基德的滑翔翼【动态规划】 F:Full Tank?【图论最短路/BFS优先队列】 G:实现堆结构 H:Subway&#xff08;迪杰斯特拉算法&a…