2997 字
15 分钟
【ADS】并行化算法
2024-12-16

并行算法公式和结论#


课后习题解 个人理解:

  1. 深度:处理需要的阶段(限定在单个处理器内)
    • 单个CPU线性查找n个元素的深度是O(n);但如果是n个,那每个查找1个元素就够了,深度是O(1)
    • 从算法来判断,每个pardo循环下,单个CPU需要承担的任务算法时间复杂度是多少,这一步pardo循环的深度就是多少(所以要尤其注意多重循环的代码)
    • serial algorithm 线性算法的时间复杂度判断,它的实际复杂度就是我们一般说的算法复杂度(一切从代码出发!)

1. 并行随机访问机(PRAM)模型#

1.1 模型基础#

  • 单位时间操作
    读、写、计算均为单位时间完成。

  • 多处理器并发模型

    • 共享内存架构,处理器通过独占读/写并发读/写访问内存。

2. 工作-深度(Work-Depth)模型#

2.1 公式定义#

  • 总工作量:
    W=树中所有节点的总数W = \text{树中所有节点的总数}

  • 深度:
    D=树的高度D = \text{树的高度}

  • 并行运行时间(P个处理器):
    T=O(WP+D)T = O\left(\frac{W}{P} + D\right)

  • 含义

    • 第一项:WP\frac{W}{P} 表示工作量被 PP 个处理器分摊后每个处理器的负担。
    • 第二项:DD 表示所有处理器必须经历的计算树深度。

2.2 WD-模式充分性定理#

  • 若一个算法在 WD 模式下表示为:
    O(W,D)O(W, D)
    则可以使用 PP 个处理器在以下时间内实现:
    T=O(WP+D)T = O\left(\frac{W}{P} + D\right)

3. 并行算法案例#

3.1 前缀和问题(Prefix-Sum)#

  • 输入
    A(1),A(2),,A(n)A(1), A(2), \dots, A(n)

  • 输出
    Prefix-Sum: Si=j=1iA(j)\text{Prefix-Sum: } S_i = \sum_{j=1}^i A(j)

  • 公式

    • 树状求和: B(h,i)=B(h1,2i1)+B(h1,2i)B(h, i) = B(h-1, 2i-1) + B(h-1, 2i)
      其中 h=1,2,,lognh = 1, 2, \dots, \log ni=1,2,,n/2hi = 1, 2, \dots, n/2^h

    • 输出: S(i)=B(logn,1)S(i) = B(\log n, 1)

  • 复杂度

    • 深度: D=O(logn)D = O(\log n)
    • 工作量: W=O(n)W = O(n)

3.2 并行求和问题#

  • 公式

    • 输入: A(1),A(2),,A(n)A(1), A(2), \dots, A(n)

    • 每一步递归: B(h,i)=B(h1,2i1)+B(h1,2i)B(h, i) = B(h-1, 2i-1) + B(h-1, 2i)
      其中 h=1,2,,lognh = 1, 2, \dots, \log ni=1,2,,n/2hi = 1, 2, \dots, n/2^h

    • 输出: Sum=B(logn,1)\text{Sum} = B(\log n, 1)

  • 复杂度

    • 深度:
      D=O(logn)D = O(\log n)
    • 工作量:
      W=O(n)W = O(n)

3.3 最大值问题#

  • 公式

    • 替代求和中的加法为取最大值:
      B(h,i)=max(B(h1,2i1),B(h1,2i))B(h, i) = \max\left(B(h-1, 2i-1), B(h-1, 2i)\right)

    • 输出:
      Max=B(logn,1)\text{Max} = B(\log n, 1)

  • 复杂度

    • 深度:
      D=O(logn)D = O(\log n)
    • 工作量:
      W=O(n)W = O(n)

3.4 归并排序中的并行排名问题#

  • 定义
    给定两个已排序数组 AABB,将其合并为一个有序数组 CC

  • 公式

    • 排名问题定义: RANK(j,A)=i若 A(i)<B(j)<A(i+1)\text{RANK}(j, A) = i \quad \text{若 } A(i) < B(j) < A(i+1)

    • 排名公式: C(i+RANK(i,B))=A(i)C(i + \text{RANK}(i, B)) = A(i)
      C(i+RANK(i,A))=B(i)C(i + \text{RANK}(i, A)) = B(i)

  • 复杂度

    • 排名:二分搜索:
      O(logn)O(\log n)
    • 合并工作量:
      W=O(n+m)W = O(n+m)

4. 随机采样与概率分析#

4.1 随机采样求最大值#

  • 算法过程

    1. 随机从输入 AA 中抽取 B(n7/8)B(n^{7/8}) 个元素。
    2. BB 估算 AA 的最大值 MM
    3. AA 中仍存在大于 MM 的元素,重复抽样。
  • 复杂度

    • 高概率下,深度: D=O(1)D = O(1)
    • 工作量: W=O(n)W = O(n)
  • 概率优化: 若期望误差为 ϵ\epsilon,可以选择 kk 使得其标准误差满足:

    k=O(1ϵ2)k = O\left(\frac{1}{\epsilon^2}\right)

4.2 (补充)问题:随机采样求最大值的并行算法#

随机采样求最大值的并行算法是一种通过在给定数据中进行随机抽样,来估计数据的最大值的算法。该方法的核心思想是通过多次采样和并行处理,减少了求解最大值的计算量,并提高了处理效率,尤其适用于大规模数据集。

问题背景#

在处理大规模数据时,传统的寻找最大值的方法(遍历整个数据集)可能会非常慢,特别是数据量巨大的情况下。通过随机采样,可以大致估算出最大值,而不必遍历所有数据,这样能够大大提高效率。

基本思想#

  1. 随机采样:从数据集 DD 中随机选择一些样本元素。
  2. 并行计算:多个处理器并行地处理不同的随机样本,并在局部计算中找到最大值。
  3. 合并结果:最终,从多个局部结果中选择出全局最大值。

算法步骤#

假设我们有 nn 个元素的数据集 D={d1,d2,,dn}D = \{d_1, d_2, \dots, d_n\},并且我们希望通过并行计算随机采样的方式来估算最大值。

  1. 随机选择样本

随机从数据集 DD 中选择 kk 个元素作为样本:

S={di1,di2,,dik}S = \{d_{i_1}, d_{i_2}, \dots, d_{i_k}\}

其中 i1,i2,,iki_1, i_2, \dots, i_k 是从 {1,2,,n}\{1, 2, \dots, n\} 中随机选出的 kk 个索引。

  1. 并行求局部最大值

将样本 SS 分配到 pp 个处理器,每个处理器计算一部分样本的最大值:

  • 处理器 T1T_1 计算样本中的最大值 max1\text{max}_1
  • 处理器 T2T_2 计算样本中的最大值 max2\text{max}_2
  • 处理器 TpT_p 计算样本中的最大值 maxp\text{max}_p
  1. 合并局部最大值

所有 pp 个处理器计算完后,最终的最大值是这些局部最大值的最大值:

maxfinal=max(max1,max2,,maxp)\text{max}_\text{final} = \max(\text{max}_1, \text{max}_2, \dots, \text{max}_p)
  1. 输出结果

返回最终的最大值 maxfinal\text{max}_\text{final}

时间复杂度#

  1. 随机采样:随机选择 kk 个样本的操作通常是 O(k)O(k)
  2. 并行计算局部最大值:将 kk 个样本分配给 pp 个处理器,每个处理器处理 k/pk/p 个元素。每个处理器计算最大值的时间复杂度为 O(k/p)O(k/p),在 pp 个处理器上并行执行,总的时间复杂度为 O(k/p)O(k/p)
  3. 合并最大值:合并 pp 个局部最大值的操作时间复杂度为 O(p)O(p)

因此,总的时间复杂度是:

O(k/p+p)O(k/p + p)

其中:

  • kk 是样本大小。
  • pp 是并行处理器的数量。

选择样本大小 kk#

为了使得估计的最大值接近真实最大值,可以利用概率论来选择适当的样本大小 kk

  • 采样误差:根据大数法则,如果 kk 足够大,采样的最大值 maxS\text{max}_S 期望值接近数据集的真实最大值 maxD\text{max}_D
  • 概率保证:选择适当的 kk,可以使得通过随机采样得到的最大值与真实最大值之间的误差在某个容忍范围内。
理论分析#

如果我们从数据集 DD 中随机选择 kk 个元素,则有以下结论:

  • 估计的最大值 maxS\text{max}_S 的期望值趋近于真实的最大值 maxD\text{max}_D
  • 误差可以通过调整 kk 来控制。如果需要更高的精度,增大 kk

通常,若期望误差为 ϵ\epsilon,可以选择 kk 使得其标准误差满足:

k=O(1ϵ2)k = O\left(\frac{1}{\epsilon^2}\right)

这意味着更高精度的估计需要更多的样本。

优缺点#

  1. 优点:

    1. 提高效率:通过并行化和随机采样,避免了对整个数据集的遍历,减少了计算量,特别适用于大规模数据集。
    2. 适用于分布式系统:可以在分布式计算环境中使用,利用多个节点进行并行计算。
    3. 可控制精度:通过调整样本大小 kk 来控制误差的大小,提供灵活性。
  2. 缺点:

    1. 近似解:这种方法得到的是近似最大值,而非确切的最大值。样本越小,结果的误差越大。
    2. 样本选择偏差:如果数据分布不均匀,某些元素可能不会出现在采样中,从而影响结果的准确性。

应用场景#

  1. 大规模数据处理:例如在大数据环境下(如 MapReduce、Hadoop 或 Spark),随机采样可以大大提高数据处理效率。
  2. 实时计算:在实时计算中,使用随机采样可以快速获取近似的最大值,从而避免了全数据遍历的延迟。
  3. 分布式系统:在分布式计算环境中,多个节点可以并行进行随机采样和局部计算,最终合并结果。

通过随机采样求最大值的并行算法,能够在大数据集上有效提高效率,并且具有较好的扩展性,适用于大规模数据分析和分布式计算任务。


5. MapReduce 模型#

5.1 MapReduce 框架公式#

  • 模型公式
    • Map(Key,Value)(Intermediate Key,Intermediate Value)(\text{Key}, \text{Value}) \to (\text{Intermediate Key}, \text{Intermediate Value})
    • Reduce(Intermediate Key,[Intermediate Values])(Key,Result)(\text{Intermediate Key}, [\text{Intermediate Values}]) \to (\text{Key}, \text{Result})

5.2 MapReduce 模型#

MapReduce 是一种用于大规模数据处理的编程模型,它最初由 Google 提出,旨在处理分布式计算环境中的海量数据。MapReduce 模型将数据处理任务分成两个主要阶段Map(映射)Reduce(归约),并通过分布式计算框架实现高效并行处理。


MapReduce 的基本概念#

MapReduce 模型包括两个主要阶段:

  1. Map(映射)阶段
    将输入数据分成若干个独立的数据块(通常是键值对),交给多个Map 函数并行处理,每个 Map 函数产生中间键值对。

  2. Reduce(归约)阶段
    对 Map 阶段产生的中间键值对进行分组和聚合(根据相同的 key 进行分组),然后将数据交给Reduce 函数进行处理,最终生成结果。

MapReduce 的两个核心函数是:

  • Map 函数(k1, v1) -> [(k2, v2)]
    输入一个键值对 (k1,v1)(k1, v1),输出一组中间键值对 (k2,v2)(k2, v2)
  • Reduce 函数(k2, [v2]) -> [(k3, v3)]
    输入一个中间键值对 (k2,[v2])(k2, [v2])(多个相同的键合并到一个键,值为一个列表),输出最终的键值对 (k3,v3)(k3, v3)

MapReduce 执行流程#

MapReduce 的执行过程包括以下几个步骤:

  1. 输入数据的分割(Split)
    输入数据被分割成若干个块(通常是 HDFS 分布式存储中的块),每个块交给一个 Map 任务处理。

  2. Map 阶段
    每个 Map 任务接收一个输入块,并将其处理成一组中间键值对 (k2,v2)(k2, v2)

  3. Shuffle 和 Sort(洗牌与排序)
    Map 任务的输出会经过洗牌排序

    • Shuffle:将相同的键 (k2)(k2) 的值发送到同一个 Reduce 任务。
    • Sort:对中间键值对根据键进行排序,便于后续 Reduce 任务处理。
  4. Reduce 阶段
    Reduce 任务接收按键分组的中间数据 (k2,[v2])(k2, [v2]),然后执行用户定义的 Reduce 函数,输出最终的结果 (k3,v3)(k3, v3)

  5. 输出结果
    Reduce 任务的输出结果通常存储在分布式文件系统(如 HDFS)中。


MapReduce 示例#

以**单词计数(Word Count)**问题为例,说明 MapReduce 的执行过程:

问题:统计文本文件中每个单词的出现次数。

输入

  • 文档1:hello world
  • 文档2:hello MapReduce

Map 阶段

  • 输入数据被分割成块,Map 函数对每一行文本进行处理,将单词拆分成键值对 (word,1)(word, 1)

中间输出

(hello, 1), (world, 1), (hello, 1), (MapReduce, 1)

Shuffle 和 Sort 阶段

  • 按照键对中间数据进行分组。

分组结果

(hello, [1, 1]), (world, [1]), (MapReduce, [1])


MapReduce 特点#

优点

  1. 简单易用:开发者只需定义 Map 和 Reduce 函数,框架负责任务调度和数据传输。
  2. 高容错性:任务失败时,框架可以自动重新执行失败的任务。
  3. 可扩展性:可以轻松扩展到成千上万个节点,处理大规模数据。
  4. 并行执行:通过将任务分成多个子任务并行执行,极大地提高了处理速度。

缺点

  1. 计算效率较低:MapReduce 需要多次读写磁盘,导致 I/O 开销较大。
  2. 编程模型有限:适合简单的数据处理任务,不适合复杂的实时计算或交互式任务。
  3. 延迟较高:由于任务调度和数据传输的开销,MapReduce 不适合实时计算。

MapReduce 应用场景#

MapReduce 广泛应用于大数据分析场景,包括:

  1. 日志分析:从海量日志中提取有用信息。
  2. 单词计数:统计文本数据中单词的出现次数。
  3. 倒排索引:构建搜索引擎的索引。
  4. 大规模排序:对大规模数据集进行排序。
  5. 数据去重:查找和去除重复数据。
【ADS】并行化算法
https://herobrine101.top/posts/ads并行化算法/
作者
发布于
2024-12-16
许可协议
CC BY-NC-SA 4.0