为什么在这种情况下会发生细分错误? Openmp问题

时间:2019-03-11 13:40:31

标签: c openmp

编写顺序程序后,我需要对其进行并行化。这只是一小部分,由于某种原因,该部分不起作用。当N > 64和4个线程时,程序开始产生分段错误。有2个线程,一切正常。我试图设置环境变量KMP_STACK_SIZE = 128m,但这对我没有帮助。可能是什么问题?

#include <omp.h>
void setMatrix(double *matrix, int size) {
    for (int i = 0; i < size; i++)
        for (int j = 0; j < size; j++) {
            if (i == j) {
                matrix[i * size + j] = 2;
            } else
                matrix[i * size + j] = 1;
        }
}

void setVector(double *vector, int size, int value) {
    for (int i = 0; i < size; i++) {
        vector[i] = value;
    }
}

void clearVec(double *vector, int size) {
    for (int i = 0; i < size; i++) {
        vector[i] = 0;
    }
}

void mulMatrAndVec(double *result, const double *matrix, const double *vector, int size) {
    clearVec(result, size);
    for (int i = 0; i < size; i++) {
        for (int j = 0; j < size; j++) {
            result[i] += matrix[i * size + j] * vector[j];
        }
    }
}


void subVectors(double *result, const double *vector1, const double *vector2, int size) {
    for (int i = 0; i < size; i++) {
        result[i] = vector1[i] - vector2[i];
    }
}
void mulMatrAndVecMP(double *result, const double *matrix, const double *vector, int place, int blockSize, int size) {
    for (int i = place; i < (place + blockSize); i++) {
        for (int j = 0; j < size; j++) {
            result[i] += matrix[i * size + j] * vector[j];
        }
    }
}

int main(int argc, char *argv[]) {
    int N = 68;

    double *A = (double *) malloc(N * N * sizeof(double));
    double *x = (double *) malloc(N * sizeof(double));
    double *b = (double *) malloc(N * sizeof(double));
    double *u = (double *) malloc(N * sizeof(double));
    double *r1 = (double *) malloc(N * sizeof(double));
    double *r2 = (double *) malloc(N * sizeof(double));
    double *z = (double *) malloc(N * sizeof(double));
    double *vec1 = (double *) malloc(N*N * sizeof(double));
    double *vec2 = (double *) malloc(N * sizeof(double));

    double a = 0;
    double bt = 0;

    int threadNum, threadCount;

    setMatrix(A, N);
    setVector(x, N, 0);
    setVector(b, N, N + 1);

    mulMatrAndVec(vec1, A, x, N);
    subVectors(r1, b, vec1, N);
    clearVec(vec1, N);

    memcpy(z, r1, N * sizeof(double));
    memcpy(r2, r1, N * sizeof(double));

    omp_set_num_threads(4);
    threadCount = omp_get_num_threads();


    #pragma omp parallel  private(threadNum) shared(threadCount, vec1, A, z)
    {
        threadNum = omp_get_thread_num();
        mulMatrAndVecMP(vec1, A, z, (threadNum * N) / threadCount, N / threadCount, N);
    }

    free(A);
    free(x);
    free(b);
    free(r1);
    free(r2);
    free(z);
    free(vec1);
    free(vec2);

    free(u);

    return 0;
}

1 个答案:

答案 0 :(得分:0)

问题是您致电

threadCount = omp_get_num_threads();

在并行块之外,因此为1,而在内部则为

mulMatrAndVecMP(vec1, A, z, (threadNum * N) / threadCount, N / threadCount, N);

越界。

设置

threadCount = 4 

相反应该解决您的问题。

您可以阅读here,该调用将返回当前团队中的线程数,并且没有当前团队。

编辑:小心,以防N无法被线程数整除:您的代码会跳过乘法的某些行。