【问题标题】:Parallel Binary Search并行二分查找
【发布时间】:2012-01-15 11:16:00
【问题描述】:

我刚刚开始学习并行编程,并且正在研究二进制搜索。

这真的不能通过添加更多处理器来优化,对吧?我知道这应该是分裂和征服,但你真的是在“减少和征服”(来自Wikipedia)。

或者你可以并行化比较吗? (如果X小于array[mid],从low搜索到mid - 1;否则如果X大于array[mid]mid + 1搜索到high,否则返回midX的索引)

或者你把数组的一半给一个处理器进行二分搜索,另一半给另一个?那岂不是很浪费?因为它是减少和征服,而不是简单的分裂和征服?想法?

【问题讨论】:

    标签: parallel-processing binary-search


    【解决方案1】:

    您可以轻松使用并行性。

    对于k 小于n 处理器,将数组拆分为n/k 组并为每个组分配一个处理器。

    对该组运行二分搜索。

    现在时间是 log(n/k)

    还有一种方法是logn/log(k+1)

    【讨论】:

    【解决方案2】:

    我认为它肯定符合并行化的条件。至少,跨越两个线程。让一个线程进行深度优先搜索,另一个线程进行广度优先搜索。获胜者是执行速度最快的算法,这可能因数据集而异。

    【讨论】:

    • 如果有读者认为我轻率,其实我不是。对于算法本身可能无法并行化的时间关键部分,使用具有不同性能特征的多种算法可能是一种有效的优化,可以使最坏情况下的 big-Oh 保持一致。
    • 如何将 DFS 或 BFS 应用于二分搜索?
    【解决方案3】:

    我在并行编程方面没有太多经验,但我怀疑这是否适合并行处理。算法的每一步都取决于执行一次比较,然后根据该比较沿着一组“路径”前进(您要么找到了你的值,要么现在必须根据比较继续在一组“方向”上搜索)。两个单独的线程执行相同的比较不会让你更快,并且单独的线程都需要依赖相同的比较来决定下一步做什么,所以他们不能真正做任何有用的、独立的工作.

    就您拆分数组的想法而言,我认为您在这种情况下只是否定了二进制搜索的好处。您的值(假设它在您的数组中)将位于数组的上半部分或下半部分。二进制搜索中的第一个比较(在中点)将告诉您应该查看哪一半。如果您更进一步,请考虑将 N 个元素的数组分解为 N 个不同的二进制搜索(并行尝试的幼稚尝试) -化)。当您不需要时,您现在正在进行 N 次比较。您正在失去二分搜索的威力,因为每次比较都会将您的搜索范围缩小到适当的子集。

    希望对您有所帮助。欢迎评论。

    【讨论】:

      【解决方案4】:

      是的,在经典意义上的并行化(多核)中,二分查找和 BST 也好不了多少。

      有一些技术,例如在每个处理器的 L1 缓存上拥有多个 BST 副本。只有一个处理器处于活动状态,但拥有多个 L1 缓存的收益可能很大(L1 为 4 个周期,L2 为 14 个周期)。

      在现实世界的问题中,您经常同时搜索多个键。

      现在,还有另一种可以提供帮助的并行化:SIMD!查看来自 Intel/UCSC/Oracle 的团队(SIGMOD 2010)的“现代 CPU 和 GPU 上的快速架构敏感树搜索”。这很酷。顺便说一句,我目前的研究项目正是基于这篇论文。

      【讨论】:

        【解决方案5】:

        并行实现可以加快二分查找,但提升不是特别显着。在最坏的情况下,二分查找所需的时间是log_2(n),其中n 是列表中元素的数量。一个简单的并行实现将主列表分解为k 子列表,以供并行线程进行bin-search。二进制搜索的最坏情况时间为log_2(n/k),实现了理论上的搜索时间减少。

        示例: 1024 条目列表使用单个线程进行二进制搜索需要多达 10 个周期。使用4 线程,每个线程只需要8 周期即可完成搜索。并且使用8 线程,每个线程需要7 周期。因此,8 线程并行二进制搜索可能比单线程模型快 30%

        但是,他的加速不应与效率的提高相混淆:与单线程二分搜索执行的10 比较相比,8 线程模型实际上执行8 * 7 = 56 比较来完成搜索。二进制搜索的并行应用程序的速度边际增益是否适合或有利于他们的应用程序,由程序员自行决定。

        【讨论】:

        • 我应该补充一点,这是一个“减少和征服”的例子,而不是通常更理想的并行实现的“分而治之”。在这种情况下,每个线程执行的问题比原始搜索小,因此速度更快,但这些问题的总和大于原始问题。如果我们可以在这里管理一个“分而治之”的实现,那么较小问题的总和将与原始单线程实现相同,除了快 k 倍(其中 k 是并行线程的数量)。跨度>
        • 30% 的加速意义重大!
        【解决方案6】:

        我很确定二进制搜索可以通过 log (M) 因子来加速,其中 M 是处理器的数量。 log(n/M) = log(n) - log(M) > log(n)/ log(M) 对于常数 M。我没有严格下限的证明,但如果 M=n,则执行时间为 O(1),再好不过了。下面是一个算法草图。

        Parallel_Binary_Search(sorted_arraylist)

        1. 将您的 sorted_arraylist 分成 M 个大小为 n/M 的块。
        2. 对每个块的中间元素应用一个比较步骤。
        3. 如果比较器发出相等信号,则返回地址并终止。
        4. 否则,请分别识别比较器发出 (>) 和 (
        5. 从发出信号 (>) 的元素之后的元素开始形成一个新的块,并在发出信号 (
        6. 如果它们是相同的元素,则返回失败并终止。
        7. 否则,Parallel_Binary_Search(Chunk)

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2015-12-10
          • 1970-01-01
          • 1970-01-01
          • 2021-03-07
          • 2014-12-31
          • 1970-01-01
          • 2012-12-24
          相关资源
          最近更新 更多