openMp动态数组访问优化

时间:2015-06-22 10:27:32

标签: c++ multithreading optimization openmp

我正在尝试使用一个或四个线程来测量并行部分的加速比。由于我的并行部分相对简单,我预计速度接近四倍。 (这是我的问题: openMp: severe perfomance loss when calling shared references of dynamic arrays) 由于我的并行部分在四个核心上的运行速度是两个核心的两倍,我相信我仍然没有找到性能损失的原因。

我想尽可能地并行化我的功能。该函数使用动态数组和私有数量的条目来更改其他动态数组的条目。因为每个迭代步骤仅使用相应循环步骤的数组条目,所以我没有不同的线程访问相同的数组条目。此外,由于访问同一缓存行中的条目,我对错误共享进行了一些考虑。我的猜测是,这是一个次要的影响,因为我的双阵列长度为5 * 10 ^ 5,并且通过为日程安排(动态,块)命令选择合理的块大小,我不希望在极少数情况下进入一个给定的缓存行,由不同的线程同时访问。在我的模拟中,我有大约80个这样的数组,因此在堆栈上分配它们并不舒服,并且为每个线程制作私有副本也是不可能的。 有没有人有想法,如何改善这个?在开始编译器优化之前,我想完全理解为什么这么慢。

让我感到惊讶的是:调用iter(parallel),parallel = false,比调用parallel = true和omp_set_num_threads(1)要慢。

main.cpp中:

int main(){

    mathClass m;
    m.fillArrays();

    double timeCount = 0.0;
    for(int j = 0; j<1000; j++){
        timeCount += m.iter(true);
    }

    printf("meam time difference = %fms\n",timeCount);
    return 0;
}

mathClass.h:

class mathClass{
    private:
        double* A;
        double* B;
        double* C;
        int length;

    public:
        double* D;

        mathClass();
        double iter(bool parallel);
        void fillArrays();
};

mathClass.cpp:

mathClass::mathClass(){
    length = 5000000;

    A = new double[length];
    B = new double[length];
    C = new double[length];
    D = new double[length];
}

void mathClass::fillArrays(){
    int temp;

    for ( int i=0; i<length; i++){
        temp = rand() % 100;
        A[i] = double(temp);

        temp = rand() % 100;
        B[i] = double(temp);

        temp = rand() % 100;
        C[i] = double(temp);
    }   
}

double mathClass::iter(bool parallel){
    double startTime;
    double endTime;
    omp_set_num_threads(4);
    startTime = omp_get_wtime();

    #pragma omp parallel if(parallel)
    {
        int alpha;                  // private in all threads

        #pragma omp for schedule(static)
        for (int i=0; i<length; i++){
            alpha = 15*A[i];    
            D[i] = C[i]*alpha + B[i]*alpha*alpha;   
        }

    }
    endTime = omp_get_wtime();
    return endTime - startTime;
}

0 个答案:

没有答案