C 单线程模式下的并行合并非常慢

C 单线程模式下的并行合并非常慢,c,algorithm,merge,parallel-processing,C,Algorithm,Merge,Parallel Processing,我有两组已排序的元素,希望以某种方式将它们合并在一起,以便以后可以并行化。我有一个简单的合并实现,它具有数据依赖性,因为它使用了maximum函数和第一个版本的并行化合并,该合并使用二进制搜索来查找秩并计算给定值的索引 getRank函数返回小于或等于给定指针的元素数 #define ATYPE int int getRank(ATYPE needle, ATYPE *haystack, int size) { int low = 0, mid; int high = size

我有两组已排序的元素,希望以某种方式将它们合并在一起,以便以后可以并行化。我有一个简单的合并实现,它具有数据依赖性,因为它使用了maximum函数和第一个版本的并行化合并,该合并使用二进制搜索来查找秩并计算给定值的索引

getRank函数返回小于或等于给定指针的元素数

#define ATYPE int

int getRank(ATYPE needle, ATYPE *haystack, int size) {
    int low = 0, mid;
    int high = size - 1;
    int cmp;
    ATYPE midVal;

    while (low <= high) {
        mid = ((unsigned int) (low + high)) >> 1;
        midVal = haystack[mid];
        cmp = midVal - needle;

        if (cmp < 0) {
            low = mid + 1;
        } else if (cmp > 0) {
            high = mid - 1;
        } else {
            return mid; // key found
        }
    }

    return low; // key not found
}
#定义类型int
int getRank(ATYPE针型、ATYPE*haystack型、int大小){
int低=0,中;
int高=大小-1;
int-cmp;
中脉型;
而(低)>1;
midVal=干草堆[mid];
cmp=中脉-针;
if(cmp<0){
低=中+1;
}否则如果(cmp>0){
高=中-1;
}否则{
return mid;//找到密钥
}
}
return low;//找不到键
}
合并算法对两个排序集a、b进行操作,并将结果存储到c中

void simpleMerge(ATYPE *a, int n, ATYPE *b, int m, ATYPE *c) {
    int i, l = 0, r = 0;

    for (i = 0; i < n + m; i++) {
        if (l < n && (r == m || max(a[l], b[r]) == b[r])) {
            c[i] = a[l];
            l++;
        } else {
            c[i] = b[r];
            r++;
        }
    }
}

void merge(ATYPE *a, int n, ATYPE *b, int m, ATYPE *c) {
    int i;
    for (i = 0; i < n; i++) {
        c[i + getRank(a[i], b, m)] = a[i];
    }
    for (i = 0; i < m; i++) {
        c[i + getRank(b[i], a, n)] = b[i];
    }
}
void simpleMerge(ATYPE*a,int n,ATYPE*b,int m,ATYPE*c){
int i,l=0,r=0;
对于(i=0;i
当有很多元素时,合并操作非常慢,并且仍然可以并行化,但是SimpleEmerge总是更快,即使它不能并行化


所以我现在的问题是,你知道更好的并行合并方法吗?如果知道,你能给我指出一个方向吗?或者我的代码很糟糕吗?

通过渐近分析,合并函数使用的算法是最好的。复杂性是O(n+m)。你找不到更好的算法,因为I/O需要O(n+m)

O(n+m)

合并
功能的复杂性:

O(n*logm+m*logn)


在没有过多考虑的情况下,我对并行化的建议是,在每个函数的中间找到一个值,使用类似于getRank函数的东西,并从那里使用简单的合并。这可以是
O(n+m+logm+logn)=O(n+m)
(即使你做了几次,但要不断地查找中间的值)。

你说得对,谢谢!我应该将这些部分拆分为逻辑块,然后对它们进行简单的合并!