读书笔记《C++并发编程实战》(8) - 设计并发代码

在线程间划分工作的技术:

    划分数据的方式:得到最优性能在很大程度上决定于数据结构的细节;
        1、开始处理前的预先划分,最简单的做法便是划分数据给不同的工作任务,
    也即将一个任务划分为多个并行的任务集,工作的线程独立运行这些任务,并在后期的化简步骤中合并结果。
        2、递归地划分数据,避免产生过多的线程,但是线程间通信可能会带来复杂性。
    划分任务的方式:
        1与2在假设原数据固定不变,对于动态生成或外部输入的数据,则应以任务类型划分工作;
    其不同类型线程执行不同类型的工作。优点:分离关注点,缺点:若任务或线程间需要通信或共享数据,则可能带来
    一定的复杂度,一般对于像两个线程间频繁通信,但与其他线程关联或通信较少,则应联合为一个线程。
        此外,对于以类型划分工作的情况,若处理多个数据集合需要应用同样的操作序列,则可以划分工作使得每个线程执行
    整个操作序列中的一个步骤,类似于工厂生产流水线或管道的方式(可能得到结果时相对以划分数据的方式会有一定的
    延时,不过后期得到每个数据集的结果会比较稳定、更好的速度输出)。

影响并发代码性能的因素:

    1、处理器的数量和结构,如单核、双核、更多核芯或多个单核处理器等不同情况下可能差异会比较大,如乒乓缓存的影响,两个单核和
    一个双核处理器上可能会有很大的差异。
    2、处理器数量增多,多个处理器访问相同的数据产生竞争,处理器越多,竞争越厉害,处理器间传递互斥等信息等导致获取和
    释放锁的时间不可接受。
    3、假共享,不同处理器可能缓存了相同的但却不共享的数据,进而导致缓存线(内存块32~64字节)所有权转移时的开销(如一个比较小的数组)。
    比较好的做法是:同一个线程访问的数据在内存中紧密相邻,而不同的线程访问的数据则分散在内存中。
    4、过于分散的数据,同一个线程访问的数据分散在不同内存位置中(缓存线),导致处理器需要加载更多的缓存、内存访问延迟导致
    性能降低,此外不同的加载缓存可能包含太多不需要的数据。
    5、过多的订阅线程或过多的任务切换,任务切换中若大量线程处于就绪状态而不是等待状态时特别突出,

为多线程性能设计数据结构:

    需要考虑的有:数据竞争问题、假共享问题、数据接近。通常可以改变数据的布局、改变分配给某线程的数据元素来提高性能。
知识兔
计算机