我想用C ++实现并行前缀和算法。我的程序应该使用输入数组x[1....N]
,它应该在数组y[N]
中显示输出。 (注意N的最大值是1000。)
到目前为止,我在维基百科上经历了许多研究论文甚至算法。 但是我的程序还应该显示每一步的输出,步骤以及操作/说明。
我想要最快的实现,比如我想尽量减少操作次数和步骤。
例如::
x = {1, 2, 3, 4, 5, 6, 7, 8 } - Input
y = ( 1, 3, 6, 10, 15, 21, 28, 36) - Output
但是,除了将y数组显示为输出外,我的程序还应显示每个步骤的操作。我也引用了这个帖子calculate prefix sum,但可以从中得到很多帮助。
答案 0 :(得分:27)
此问题的答案在于:http://http.developer.nvidia.com/GPUGems3/gpugems3_ch39.html和http://www.cs.cmu.edu/~guyb/papers/Ble93.pdf。 NVidia文章使用CUDA GPU提供了最佳实现,卡内基梅隆大学PDF论文解释了该算法。我还使用MPI实现了一个O(n / p)前缀和,你可以在这里找到:In my github repo
这是通用算法的伪代码(独立于平台):
示例3.工作效率和扫描算法的上扫描(减少)阶段(Blelloch 1990之后)
for d = 0 to log2(n) – 1 do
for all k = 0 to n – 1 by 2^(d+1) in parallel do
x[k + 2^(d+1) – 1] = x[k + 2^d – 1] + x[k + 2^(d+1) – 1]
示例4.工作效率并行和扫描算法的向下扫描阶段(Blelloch 1990之后)
x[n – 1] = 0
for d = log2(n) – 1 down to 0 do
for all k = 0 to n – 1 by 2^(d+1) in parallel do
t = x[k + 2^d – 1]
x[k + 2^d – 1] = x[k + 2^(d+1) – 1]
x[k + 2^(d+1) – 1] = t + x[k + 2^(d+1) – 1]
x 是输入数据, n 是输入的大小, d 是并行度(CPU数量) 。这是一个共享内存计算模型,如果它使用分布式内存,则需要向该代码添加通信步骤,就像我在提供的Github示例中所做的那样。 p>
答案 1 :(得分:2)
我只实现了数组中所有元素的总和(Blelloch的向上扫描减少部分),而不是在java / opencl中使用Aparapi(https://code.google.com/p/aparapi/)的完整前缀和。它在https://github.com/klonikar/trial-aparapi/blob/master/src/trial/aparapi/Reducer.java处可用,它是为一般块大小(在代码中称为localBatchSize)而不是2而编写的。我发现块大小为8最适合我的GPU。
虽然实现工作(总和计算是正确的),但它的执行比顺序总和差得多。在我的 core-i7(8核心)CPU 上,8388608(8MB)数字的顺序总和约为12ms,GPU上的并行执行( NVidia Quadro K2000M具有384核)大约需要100毫秒。我甚至优化了在计算之后仅传输最终总和而不是整个数组。如果没有这种优化,则需要20ms。该实现似乎是根据@ marcel-valdez-orozco的回答中描述的算法。
答案 2 :(得分:-28)
以下代码将完成工作
void prfxSum()
{
int *x=0;
int *y=0;
int sum=0;
int num=0;
int i=0;
cout << "Enter the no. of elements in input array : ";
cin >> num;
x = new int[num];
y = new int[num];
while(i < num)
{
cout << "Enter element " << i+1 << " : ";
cin >> x[i++];
}
cout << "Output array :- " << endl;
i = 0;
while(i < num)
{
sum += x[i];
y[i] = sum;
cout << y[i++] << ", ";
}
delete [] x;
delete [] y;
}
以下是执行时的输出
Enter the no. of elements in input array : 8
Enter element 1 : 1
Enter element 2 : 2
Enter element 3 : 3
Enter element 4 : 4
Enter element 5 : 5
Enter element 6 : 6
Enter element 7 : 7
Enter element 8 : 8
Output array :-
1, 3, 6, 10, 15, 21, 28, 36
您可以通过从文件中提供数据来避免用户输入数组x []的1000个元素。