zoukankan      html  css  js  c++  java
  • 当优化扩展到多核时

    当优化扩展到多核时

    "软件开发没有银弹,我们能做的就是选择和平衡;"

    上一篇文章我们聊了在单线程下程序优化的5个方向(ref:《程序优化的5个方向》);当单核优化到极值后,就到了多任务的情况;
    想起来很清晰,单个任务分解成多个任务,让多个cpu同时来工作,并行执行,效率自然就上去了;
    但,未必就这么简单;

    任务分解的粒度

    首先,我们需要确定,我们的单个任务是否可以分解;比如解析很多个文件,这样的任务划分成多个很简单;但如果是一个耗时的串行逻辑计算,后期的计算依赖前期的结果,这样就不好拆分;这种形式可能需要在更高层次上来拆分;

    数据竞争

    编程就是计算和数据;计算并行了,但数据还是访问同一份,访问共同的资源会产生资源竞争;
    如果不进行控制,可能导致同一份数据重复计算(多个读的场景)或是脏数据的产生(有回写的场景);

    引入锁

    为了让数据访问有序进行,需要引入锁来防止脏数据;
    控制锁的粒度,是个需要精心考虑的话题;
    比如对于大量读少量写的场景,相比一视同仁的加锁,使用读写锁能显著提升效率;
    我们日常能接触到的产品中,数据库是个用锁高手,在更新数据的时候,是锁住行,还是列、或是表,不同的粒度性能相差明显;

    惊群现象

    考虑这样的场景:多个线程都在等在一个锁,如果可以拿到锁,线程就开始工作(线程池)
    当锁被释放时,如果唤醒多个线程可能会产生 惊群现象;
    解决方案:
    使用单线程方案/处理accpet连接 处理等待锁的操作,让任何时刻只有一个线程在等待锁;
    更多细节参考:
    《客户-服务器程序设计方法》中 预先创建线程池,每个线程各自accept 一节

    数据复制

    让每个线程使用自己的数据,让数据不共有,这样能去掉资源竞争,去掉锁;
    将数据复制为多份,减少竞争,各自访问各自的数据;
    但这又引入了一个新的问题:如果各个线程回写了数据,如何保证这么数据的一致性?
    毕竟它们代表的其实是一份数据;

    涉及到数据的一致性,多份数据之间的同步又是个难题;

    数据分片

    那好,换个思路,不使用数据复制;我们使用数据分片;分片这个思想更容易想到,既然“计算”被划分为多个小任务了,那么数据也可以同样处理;
    将数据分片,每份数据存的内容不相同,它们之间没有共同点;
    这样,数据访问没有数据竞争,同时由于数据不同,也不涉及到数据一致性同步的问题;
    但,分片远远没有想的那么美好;
    分片导致了每个线程看到数据不再是全集,而是片段;这就注定了这个线程只能处理这部分的特定数据;这样,线程之间的计算失去了可替换性;某种工作只能在特定的线程上处理;
    而如果有个任务需要访问所有的数据,这样就变得更加复杂;
    原来,分片之后,我们将难题向上推了,推到线程层面,需要考虑到业务逻辑层面的处理;
    这样,可能更加复杂;

    ok,想要速度更快,使用多核来处理,需要面对更多的问题;
    将单机扩展多机集群,涉及到架构层面来看,其实我们的面对的问题是类似的;
    参考:《大型网站技术架构》读书笔记[2] - 架构的模式

    软件开发没有银弹,我们能做的就是选择和平衡;

    Posted by: 大CC | 13AUG,2015
    博客:blog.me115.com [订阅]
    Github:大CC

  • 相关阅读:
    20145216 史婧瑶《信息安全系统设计基础》第一周学习总结
    20145216史婧瑶《信息安全系统设计基础》第0周学习总结
    20145216《java程序设计》课程总结
    20145216史婧瑶《Java程序设计》第10周学习总结
    20145216史婧瑶《Java程序设计》第五次实验报告
    20145216史婧瑶《Java程序设计》第四次实验报告
    20145216史婧瑶《Java程序设计》第9周学习总结
    20145216史婧瑶《Java程序设计》第三次实验报告
    20145216史婧瑶《Java程序设计》第8周学习总结
    20145220韩旭飞第五周博客
  • 原文地址:https://www.cnblogs.com/me115/p/4726228.html
Copyright © 2011-2022 走看看