Algorithm 如何将这种顺序迭代二进制搜索转换为并行算法?
我有一个数组(A),其中有n个元素,保证可以排序,我需要在并行系统中对它们执行二进制搜索。我首先做了这个二进制搜索算法。它是迭代的,因为我还不知道如何将递归合并到并行处理中Algorithm 如何将这种顺序迭代二进制搜索转换为并行算法?,algorithm,parallel-processing,sequential,Algorithm,Parallel Processing,Sequential,我有一个数组(A),其中有n个元素,保证可以排序,我需要在并行系统中对它们执行二进制搜索。我首先做了这个二进制搜索算法。它是迭代的,因为我还不知道如何将递归合并到并行处理中 /* Looking for element k in array A of length n */ min = 0; max = n - 1; while(min <= max) { midpoint = min + ((max-min)/2); //index if(A[midpoint] >
/* Looking for element k in array A of length n */
min = 0;
max = n - 1;
while(min <= max)
{
midpoint = min + ((max-min)/2); //index
if(A[midpoint] > k) //discard upper half
max = midpoint - 1;
else if(A[midpoint] < k) //discard lower half
min = midpoint + 1;
else
return midpoint; //Found k, return index
}
return -1; //not found
/*在长度为n的数组中查找元素k*/
最小值=0;
max=n-1;
while(mink)//丢弃上半部分
最大值=中点-1;
else如果(A[中点]
在并行算法中,我可以访问p处理器,它是一个允许并发读取但允许独占写入的系统。真正的问题是我仍然在按顺序思考。也就是说,我似乎看不出有任何方法可以使用多个处理器来实现这一点,因为您不能在不知道中点值的情况下“丢弃”阵列中不需要的部分。这似乎是天生的顺序
伪代码:
Global: //Variables accessible by all processors
index; //index of k
p; //number of processors
i; //the i^th processor
n; //number elements in array A
A[0, 1, ... , (n-1)];
local: //Variables accessible by only the owning processor
//Not sure what I need yet
Begin
Spawn(P1, P2 . . . P(p-1)); //"create" the p processors
for all P where 0 <= i <= (p-1) do //each processor does the following code
//I'm stuck here
endfor
End
Global://所有处理器均可访问的变量
指数//k指数
p//处理器数量
一,//第i个处理器
n//对数组A中的元素进行编号
A[0,1,…(n-1)];
local://只能由拥有的处理器访问的变量
//还不确定我需要什么
开始
产卵(P1,P2…P(P-1))//“创建”p处理器
对于所有P,其中0,虽然在技术上可以使二进制搜索并行运行,但我不建议这样做
并行运行的最佳算法是那些可以同时运行的离散元素彼此分离的算法。例如,将3d图形渲染到视频中是很好的,因为每个帧都是独立的,可以交给单独的处理器
您可以将树划分为多个段,这样每个处理器都可以处理一些事情,但是考虑到二进制搜索的性质,许多处理器中只有一个会找到答案,因此浪费了所有其他在其段中没有搜索元素的处理器的计算工作。这甚至没有考虑线程的开销
另一方面,如果你在一棵二叉树上进行一系列的搜索,那将是另一回事。您可以拥有一个作业队列,所有线程都可以从该队列馈送、执行二进制搜索并响应。这样,您可以并行运行多个搜索,而不是搜索的一部分。如果您希望进一步优化它,还可以实现缓存
简言之,不要试图在处理器之间分割单个二进制搜索,因为除了浪费处理器时间之外,您不会得到任何东西。但是如果你在做很多搜索,你可以通过并行运行这些搜索来获得收益。虽然从技术上讲,并行运行二进制搜索是可能的,但我不建议这样做
并行运行的最佳算法是那些可以同时运行的离散元素彼此分离的算法。例如,将3d图形渲染到视频中是很好的,因为每个帧都是独立的,可以交给单独的处理器
您可以将树划分为多个段,这样每个处理器都可以处理一些事情,但是考虑到二进制搜索的性质,许多处理器中只有一个会找到答案,因此浪费了所有其他在其段中没有搜索元素的处理器的计算工作。这甚至没有考虑线程的开销
另一方面,如果你在一棵二叉树上进行一系列的搜索,那将是另一回事。您可以拥有一个作业队列,所有线程都可以从该队列馈送、执行二进制搜索并响应。这样,您可以并行运行多个搜索,而不是搜索的一部分。如果您希望进一步优化它,还可以实现缓存
简言之,不要试图在处理器之间分割单个二进制搜索,因为除了浪费处理器时间之外,您不会得到任何东西。但是,如果您正在进行多个搜索,您可以通过并行运行多个搜索来获得收益。与所有要并行解决的问题一样……这在很大程度上取决于数据的大小、消息/共享内存的速度以及您的需求
写锁有多快,同步有多快?如果它们足够快(例如,在一台机器上使用共享内存),并且您的数据量足够大,那么一种特定的“拆分并运行”技术可能会起作用。你可以这样想:
二进制搜索是一种分而治之的方法,在每次迭代后更新正在检查的范围-范围在每次迭代时减半。您可以将当前范围划分为p
个部分,每个进程负责其中一个部分,而不是将当前范围划分为2个部分;在每次迭代中,“获胜”块(目标值在其范围内的块)将要搜索的新范围写入内存,并且在开始下一次迭代之前同步进程。如果你有足够的数据,从每次将数据减半到每次将数据减少p
都可能是一场胜利。您将从$O(log_2(x))$变为$O(log_p(x))$
这种方法只有在写入和同步足够快的情况下才有效,因为它依赖于大量的写入和同步。如果您跨集群执行此操作,那么这些将变得非常昂贵。如果进程之间的通信很困难,那么您最好在链接到的另一篇文章中建议“拆分并运行”。具体来说,将排序列表中的每个p
th元素放在不同的节点上。然后,当请求传入时,对所有节点进行二进制搜索。如果数组中的值是唯一的,则只有一个节点会找到t