【问题标题】:Run different parts of code on different cores using OpenMP使用 OpenMP 在不同内核上运行不同部分的代码
【发布时间】:2017-03-03 22:29:19
【问题描述】:

我有一个程序,它可以分成一些彼此没有数据依赖关系的部分。我想使用 OpenMP 在处理器的不同内核上运行这些部分。我已经尝试过使用下面的代码,但是在单核上执行比在多核上执行花费的时间更少。你能告诉我哪里出错了吗?

        #include<stdio.h>
        #include<stdlib.h>
        #include<omp.h>

        void serial(){

            unsigned int a[10],b[10],c[10];
            long long int i,j,k;
            for(i=0;i<10;i++){
                b[i]=rand();
                c[i]=rand();
            }

            a[0]=b[0]-c[0];
            a[1]=b[1]*c[1];
            a[2]=b[2]^c[2];
            a[3]=b[3]|c[3];
            a[4]=(b[4]*5)+c[4];
            a[5]=(!b[5])&c[5];
            a[6]=b[6]+c[6];
            a[7]=b[7]-c[7];
            a[8]=b[8]&c[8];
            a[9]=b[9]^c[9];

            for(i=0;i<10;i++){
                printf("a[%lld]=%u\t",i,a[i]);
            }
        }

        void parallel(){

            unsigned int a[10],b[10],c[10];
            int num_thread;
            long long int i,j,k;
            for(i=0;i<10;i++){
                b[i]=rand();
                c[i]=rand();
            }
            #pragma omp parallel
            {
            int ID;
            long long int i1;
            ID=omp_get_thread_num();
            if(ID==0){
                printf("ID is %d\n",ID);
                a[0]=b[0]-c[0];
                a[1]=b[1]*c[1];
                a[2]=b[2]^c[2];
                a[3]=b[3]|c[3];
                a[4]=(b[4]*5)+c[4];
                }
            else{
                printf("ID is %d\n",ID);
                a[5]=(!b[5])&c[5];
                a[6]=b[6]+c[6];
                a[7]=b[7]-c[7];
                a[8]=b[8]&c[8];
                a[9]=b[9]^c[9];                 
                }
            }
            for(i=0;i<10;i++){
                printf("a[%lld]=%u\t",i,a[i]);
            }
        }



        void main(){

            double time;
            unsigned long long int clock1,clock2;

            time=omp_get_wtime();
            serial();   
            time=omp_get_wtime()-time;
            printf("\nSerial time : %f \n",time);

            time=omp_get_wtime();
            parallel();
            time=omp_get_wtime()-time;
            printf("\nParallel time : %f\n",time);

        }

当我运行上述代码时,并行程序的运行时间是串行程序的 4 倍。 编辑 #1 更新了代码

            #include<stdio.h>
            #include<stdlib.h>
            #include<omp.h>
            unsigned long long int N=1000;
            unsigned long long int *a1,*b1,*c1,*d1;
            void init(){ //just to put some random data

                unsigned long long int i;
                a1=(unsigned long long int *)malloc(N*sizeof(unsigned long long int));
                b1=(unsigned long long int *)malloc(N*sizeof(unsigned long long int));
                c1=(unsigned long long int *)malloc(N*sizeof(unsigned long long int));
                d1=(unsigned long long int *)malloc(N*sizeof(unsigned long long int));
                for(i=0;i<N;i++){
                    a1[i]=rand();
                    b1[i]=rand();
                    c1[i]=rand();
                    d1[i]=rand();
                }
            }
            void seq(){//runs on one core 

                unsigned long long int i;
                unsigned long long int a[N],b[N],c[N],d[N];

                for(i=0;i<N;i++){
                    a[i]=a1[i];
                    b[i]=b1[i];
                    c[i]=c1[i];
                    d[i]=d1[i];
                }

                for(i=0;i<N;i++){
                    a[i]=a[i]+b[i];
                }

                for(i=0;i<N;i++){
                    c[i]=c[i]+d[i];
                }

            }
            void parallel(){//runs on 2 cores

                unsigned long long int i;
                unsigned long long int a[N],b[N],c[N],d[N];

                for(i=0;i<N;i++){
                    a[i]=a1[i];
                    b[i]=b1[i];
                    c[i]=c1[i];
                    d[i]=d1[i];
                }
                #pragma omp parallel
                {
                    int ID;
                    ID=omp_get_thread_num();
                    if(ID==0){
                        for(i=0;i<N;i++){
                            a[i]=a[i]+b[i];
                        }
                    }
                    else{
                        for(i=0;i<N;i++){
                            c[i]=c[i]+d[i];
                        }
                    }
                }
            }

            void main(){

                init();
                double time;

                time=omp_get_wtime();
                seq();
                time=omp_get_wtime()-time;
                printf("\n time for serial execution : %f\n",time);

                time=omp_get_wtime();
                parallel();
                time=omp_get_wtime()-time;
                printf("\ntime for parallel execution : %f\n",time);
            }

并行执行仍然比串行执行慢两倍。 该程序在 Intel core2 处理器上运行。

【问题讨论】:

  • 存在与并行化相关的开销,即使线程之间没有数据依赖关系。除了所有其他考虑因素之外,您提供的计算非常短;如果这种情况下的开销没有克服并行化带来的任何好处,我实际上会感到惊讶。
  • 感谢您的回复。这不是我的实际问题,我把它放在这里是为了说明。我会更新代码。
  • 你为什么不使用#pragma omp parallel for,你在哪里指定它应该创建多少线程?如果您一遍又一遍地使用 3 个线程执行第二部分,则需要更长的时间。你得到的实际时间是多少?
  • @KamiKaze 部分代码不相似。我想在两个不同的内核上运行代码的两个不同部分。我不明白在这种情况下使用#pragma omp parallel for 会有什么帮助。
  • 我认为你的工作还不够。将 N 设置为 1000000。这可能就足够了。我参与了一个使用 pthrds 并行化神经网络的项目,除非神经网络实际上有数千个节点,否则并行化是浪费时间。今天的计算机速度非常快。

标签: c parallel-processing openmp


【解决方案1】:

您正在运行的操作(只是 '+' )太简单了,无法利用并行化,因为 omp 的额外开销也很重要。 尝试更复杂一点的操作:

for(i=0;i<N;i++){
    a[ i ] = sqrtf( a[ i ] + b[ i ]);
}

for(i=0;i<N;i++){
    c[ i ] = sqrtf( c[ i ] + d[ i ]);
}

您在 parallel() 函数中有非并行初始化循环。最好在并行 for 循环中初始化 a 和 b:

    if(ID==0)
    {
        for(int i=0;i<N;i++)
        {
            a[ i ] = a1[ i ];
            b[ i ] = b1[ i ];
            a[ i ] = sqrtf(a[ i ] + b[ i ]);
        }
    }
    else
    {
        for(int i=0;i<N;i++)
        {
            c[ i ] = c1[ i ];
            d[ i ] = d1[ i ];
            c[ i ] = sqrtf( c[ i ] + d[ i ]);
        }
    }
}

当然,直接使用a1、b1、c1、d1会更好……

【讨论】:

    猜你喜欢
    • 2018-05-29
    • 1970-01-01
    • 1970-01-01
    • 2018-03-08
    • 2010-12-20
    • 2013-08-09
    • 2015-09-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多