.net中并行开发优化(代码片段)

zhao123 zhao123     2022-12-22     582

关键词:

让我们考虑一个简单的编程挑战:对大数组中的所有元素求和。现在可以通过使用并行性来轻松优化这一点,特别是对于具有数千或数百万个元素的巨大阵列,还有理由认为,并行处理时间应该与常规时间除以CPU核心数一样多。事实证明,这一壮举并不容易实现。我将向您展示几种并行执行此操作的方法,它们如何改善或降低性能以及以某种方式影响性能的所有细节。

简单的循环方法

private const int ITEMS = 500000;
private int[] arr = null;

public ArrayC()

    arr = new int[ITEMS];
    var rnd = new Random();
    for (int i = 0; i < ITEMS; i++)
    
        arr[i] = rnd.Next(1000);
    


public long ForLocalArr()

    long total = 0;
    for (int i = 0; i < ITEMS; i++)
    
        total += int.Parse(arr[i].ToString());
    

    return total;


public long ForeachLocalArr()

    long total = 0;
    foreach (var item in arr)
    
        total += int.Parse(item.ToString());
    

    return total;

只需要迭代循环就可以计算出结果,超级简单,这里没有用直接相加求出结果,原因是直接求出结果,发现每次基本的运行都比并行快,但是实际上,并行处理没有那么简单,所以这里的加法就简单的处理下total += int.Parse(arr[i].ToString())。现在,让我们尝试用并行性来打败数组迭代吧。

首次尝试

private object _lock = new object();

public long ThreadPoolWithLock()

    long total = 0;
    int threads = 8;
    var partSize = ITEMS / threads;
    Task[] tasks = new Task[threads];
    for (int iThread = 0; iThread < threads; iThread++)
    
        var localThread = iThread;
        tasks[localThread] = Task.Run(() =>
        
            for (int j = localThread * partSize; j < (localThread + 1) * partSize; j++)
            
                lock (_lock)
                
                    total += arr[j];
                
            
        );
    

    Task.WaitAll(tasks);
    return total;

请注意,您必须使用localThread变量来“保存”该iThread时间点的值。否则,它将是一个随着for循环前进而变化的捕获变量。当数据最后打的时候并行已经比普通的快了,但是发现快的不多,说明还可以优化

再次优化

public long ThreadPoolWithLock2()

    long total = 0;
    int threads = 8;
    var partSize = ITEMS / threads;
    Task[] tasks = new Task[threads];
    for (int iThread = 0; iThread < threads; iThread++)
    
        var localThread = iThread;
        tasks[localThread] = Task.Run(() =>
        
            long temp = 0;
            for (int j = localThread * partSize; j < (localThread + 1) * partSize; j++)
            
                temp += int.Parse(arr[j].ToString());
            

            lock (_lock)
            
                total += temp;
            
        );
    

    Task.WaitAll(tasks);
    return total;

增加设置临时变量,减少lock次数,发现运行效果已经有质的提高,提高了几倍。忽然想起,有个Parallel.For的方法,研究性能是否可以更快。

Parallel.For优化

public long ParallelForWithLock()

    long total = 0;
    int parts = 8;
    int partSize = ITEMS / parts;
    var parallel = Parallel.For(0, parts, new ParallelOptions(), (iter) =>
    
        long temp = 0;
        for (int j = iter * partSize; j < (iter + 1) * partSize; j++)
        
            temp += int.Parse(arr[j].ToString());
        

        lock (_lock)
        
            total += temp;
        
    );
    return total;

运行结果比普通迭代快,但是没有ThreadPool快,但是觉得Parallel.For还可以继续优化,也许可以更快

Parallel.For继续优化

public long ParallelForWithLock2()

    long total = 0;
    int parts = 8;
    int partSize = ITEMS / parts;
    var parallel = Parallel.For(0, parts,
        localInit: () => 0L, // Initializes the "localTotal"
        body: (iter, state, localTotal) =>
        
            for (int j = iter * partSize; j < (iter + 1) * partSize; j++)
            
                localTotal += int.Parse(arr[j].ToString());
            

            return localTotal;
        ,
        localFinally: (localTotal) =>  total += localTotal; );
    return total;

运行效果已经很快,和ThreadPool优化过的差不多,有些时候更快

结论和总结

并行化优化肯定可以提高性能,但是这取决于很多因素,每个案例都应该进行测量和检查。
当各种线程需要通过某种锁定机制相互依赖时,性能会显着降低。

50万数据运行结果

技术图片

《性能优化》并发与并行(代码片段)

...技术。本文带来的是性能优化中的第一利器:并发与并行。除了核心原理介绍外,我将结合我自身的过去的实战经验,给出一些自己在使用上的建议,希望对大家有帮助。不多废话,直接 查看详情

详解sql优化必备:并行执行框架和执行计划(代码片段)

摘要:在关系型数据库中,优化器是数据库的核心组件之一,由于一些列因素都会影响语句的执行,优化器综合权衡各个因素,在众多的执行计划中选择认为是最佳的执行计划。本文分享自华为云社区《华为... 查看详情

greatsql重磅特性,innodb并行并行查询优化测试(代码片段)

...了两个重磅特性:InnoDB事务锁优化 以及 InnoDB引擎的并行查询优化,这两个特性是由华为鲲鹏计算团队贡献的Patch合并而来。InnoDB并行查询优化怎么实现的?根据B+树的特点,可以将B+树划分为若干子树,... 查看详情

python入门-4控制语句:09循环代码优化技巧(重要)-zip()并行迭代(代码片段)

一:循环代码优化  虽然计算机越来越快,空间也越来越大,我们仍然要在性能问题上“斤斤计较”。编写循环时,遵守下面三个原则可以大大提高运行效率,避免不必要的低效计算:    1.尽量减少循环内部不必... 查看详情

8天玩转并行开发——第五天同步机制(下)(代码片段)

...篇,我们继续说下.net4.0中的同步机制,是的,当出现了并行计算的时候,轻量级别的同步机制应运而生,在信号量这一块出现了一系列的轻量级,今天继续介绍下面的3个信号量 CountdownEvent,SemaphoreSlim,ManualResetEventSlim。 ... 查看详情

25.flink监控什么是metricsmetrics分类flink性能优化的方法合理调整并行度合理调整并行度flink内存管理sparkvsflink时间机制容错机制等(代码片段)

...能优化26.1.复用对象26.2.数据倾斜26.3.异步IO26.4.合理调整并行度27.Flink内存管理28.SparkVSFlink28.1.应用场景28.2.API28.3.核心角色/流程原理28.3.1.spark28.3.2.Flink28.4.时间机制28.5.容错机制28.6.窗口28.7.整合Kafka28.8.其他的28.9.单独补充:流式计... 查看详情

25.flink监控什么是metricsmetrics分类flink性能优化的方法合理调整并行度合理调整并行度flink内存管理sparkvsflink时间机制容错机制等(代码片段)

...能优化26.1.复用对象26.2.数据倾斜26.3.异步IO26.4.合理调整并行度27.Flink内存管理28.SparkVSFlink28.1.应用场景28.2.API28.3.核心角色/流程原理28.3.1.spark28.3.2.Flink28.4.时间机制28.5.容错机制28.6.窗口28.7.整合Kafka28.8.其他的28.9.单独补充:流式计... 查看详情

springboot开发案例之多任务并行+线程池处理

前言前几篇文章着重介绍了后端服务数据库和多线程并行处理优化,并示例了改造前后的伪代码逻辑。当然了,优化是无止境的,前人栽树后人乘凉。作为我们开发者来说,既然站在了巨人的肩膀上,就要写出更加优化的程序。... 查看详情

neon优化之《简介》(代码片段)

...典型的例子:http://hilbert-space.de/?p=22 一、入门 1.并行操作模式的模式[Mapping,Reduce,Scatter,Stencil]2.NEON指令使用举例,NEON指令提供的核心能力有数据的 查看详情

8天玩转并行开发——第六天异步编程模型(代码片段)

 在.net里面异步编程模型由来已久,相信大家也知道Begin/End异步模式和事件异步模式,在task出现以后,这些东西都可以被task包装起来,可能有人会问,这样做有什么好处,下面一一道来。 一:Begin/End模式1:委托  ... 查看详情

并行编程模型1(代码片段)

转自https://blog.csdn.net/scape1989/article/details/61622457并行编程模型2017年03月12日17:19:33阅读数:1846在计算领域,并行编程模型是并行计算机体系架构的一种抽象,它便于编程人员在程序中编写算法及其组合。一个编程模型的价值可以... 查看详情

cuda编程进一步并行(代码片段)

CUDA编程(六)进一步并行在之前我们使用Thread完成了简单的并行加速,虽然我们的程序运行速度有了50甚至上百倍的提升,但是根据内存带宽来评估的话我们的程序还远远不够,在上一篇博客中给大家介绍了... 查看详情

8天玩转并行开发——第二天task的使用(代码片段)

   在我们了解Task之前,如果我们要使用多核的功能可能就会自己来开线程,然而这种线程模型在.net4.0之后被一种称为基于“任务的编程模型”所冲击,因为task会比thread具有更小的性能开销,不过大家肯定会有... 查看详情

从view绘制谈性能优化(代码片段)

...注明出处:http://blog.csdn.net/wl9739/article/details/57416433在开发过程中,往往会听到“性能优化”这个概念,这个概念很大,比如网络性能优化、耗电量优化等等,对我们开发者而言,最容易做的,或者是影... 查看详情

高性能并行编程与优化|第01讲回家作业(代码片段)

目录1 问题2 代码和编译结果3 使用方式4 相关链接5 躺坑记录1 问题1 CMakeError:CMakecannotdeterminelinkerlanguagefortarget:stbiw在未增加stb_image_write.cpp时,可以直接在外层的CMakeLists.txt里添加这个解决:set_target_properties(stbiwPROPE 查看详情

使用javacompletablefuture实现流水线化的并行处理,深度实践总结(代码片段)

...我们想要动手进行优化的时候呢,就会涉及到串行处理改并行处理的问题。在JAVA中并行处理的能力支持已经相对完 查看详情

《性能优化》并发与并行(代码片段)

...技术。本文带来的是性能优化中的第一利器:并发与并行。除了核心原理介绍外,我将结合我自身的过去的实战经验,给出一些自己在使用上的建议,希望对大家有帮助。不多废话,直接开怼。正文1、并发和... 查看详情

zellij-一个典型的rust程序的性能优化案例(代码片段)

...发过程中,尤其是在程序调试的过程中,通常会并行开许多Terminal窗口。不过时间一久,可能就会忘了每个终端都是用于来干嘛的。于是,如何让界面保持清爽,同时又不降低工作效率,成了很多开发者的... 查看详情