Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/variables/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Pthreads 在具有4个双核Cpu的服务器上使用1-8个线程的程序出现计时问题';s_Pthreads_Openmp_Benchmarking - Fatal编程技术网

Pthreads 在具有4个双核Cpu的服务器上使用1-8个线程的程序出现计时问题';s

Pthreads 在具有4个双核Cpu的服务器上使用1-8个线程的程序出现计时问题';s,pthreads,openmp,benchmarking,Pthreads,Openmp,Benchmarking,我在我大学的服务器上运行一个程序,该服务器有4个双核AMD Opteron(tm)处理器2210,操作系统是Linux版本2.6.27.25-78.2.56.fc9.x86_64。我的程序实现了康威生活游戏,它使用pthreads和openmp运行。我使用GetTimeOfDay()函数使用1-8个线程对程序的并行部分计时。但时机似乎不太合适。我使用1个线程获得了最大的时间(正如预期的那样),然后时间变小了。但我得到的最短时间是当我使用4个线程时 下面是一个使用阵列1000x1000的示例 使用

我在我大学的服务器上运行一个程序,该服务器有4个双核AMD Opteron(tm)处理器2210,操作系统是Linux版本2.6.27.25-78.2.56.fc9.x86_64。我的程序实现了康威生活游戏,它使用pthreads和openmp运行。我使用GetTimeOfDay()函数使用1-8个线程对程序的并行部分计时。但时机似乎不太合适。我使用1个线程获得了最大的时间(正如预期的那样),然后时间变小了。但我得到的最短时间是当我使用4个线程时

下面是一个使用阵列1000x1000的示例

使用1个线程9,62秒,使用2个线程4,73秒,使用3~3.64秒,使用4~2.99秒,使用5~4,19秒,使用6~3.84秒,使用7~3.34秒,使用8~3.12秒

上面的计时是在我使用pthreads时进行的。当我使用openmp时,计时更小,但遵循相同的模式

我预计时间会从1-8减少,因为有4个双核CPU?我认为因为有4个CPU,每个CPU有2个内核,所以可以同时运行8个线程。它是否与服务器运行的操作系统有关

我还在另一台服务器上测试了相同的程序,该服务器有7个双核AMD Opteron(tm)处理器8214,运行Linux版本2.6.18-194.3.1.el5。我得到的时间正是我所期望的。从1(最大)到8(最小执行时间),计时变得更小

该程序使用pthreads和openmp实现了正确的生活游戏,我只是不明白为什么计时与我发布的示例类似。总之,我的问题是:

1) 系统上可以同时运行的线程数取决于CPU的内核?虽然每个cpu都有多个内核,但它只取决于cpu?这取决于所有以前的版本和操作系统

2) 这与我将1000x1000数组除以线程数的方式有关吗?但是如果我这样做了,那么openmp代码就不会给出相同的计时模式了

3) 为什么我会有这样的时间安排

这是我在openmp中使用的代码:

#define  Row 1000+2
#define Col 1000+2 int num; int (*temp)[Col]; int (*a1)[Col]; int (*a2)[Col];

int main() {
        int i,j,l,sum;
        int array1[Row][Col],array2[Row][Col];
        struct timeval tim;
        struct tm *tm;
        double start,end;
        int st,en;

           for (i=0; i<Row; i++)
                for (j=0; j<Col; j++)
                   {
                    array1[i][j]=0;
                    array2[i][j]=0;
                  }
        array1[3][16]=1;
        array1[4][16]=1;
        array1[5][15]=1;
        array1[6][15]=1;
        array1[6][16]=1;
        array1[7][16]=1;
        array1[5][14]=1;
        array1[4][15]=1;
        a1=array1;
        a2=array2;
        printf ("\nGive number of threads:");
        scanf("%d",&num);

        gettimeofday(&tim,NULL);
        start=tim.tv_sec+(tim.tv_usec/1000000.0); omp_set_num_threads(num);
        #pragma omp parallel private(l,i,j,sum)
        {

                printf("Number of Threads:%d\n",omp_get_num_threads());
                for (l=0; l<100; l++)
                        {
                        #pragma omp for
                        for (i=1; i<(Row-1); i++)
                        {
                                for (j=1; j<(Col-1); j++)
                                {  
                                        sum=a1[i-1][j-1]+a1[i-1][j]+a1[i-1][j+1]+a1[i][j-1]+a1[i][j+1]+a1[i+1][j-1]+a1[i+1][j]+a1[i+1][j+1];
                                        if ((a1[i][j]==1) && (sum==2||sum==3))
                                                a2[i][j]=1;
                                        else if ((a1[i][j]==1) && (sum<2))
                                                a2[i][j]=0;
                                        else if ((a1[i][j]==1) && (sum>3))
                                                a2[i][j]=0;
                                        else if ((a1[i][j]==0 )&& (sum==3))  
                                                a2[i][j]=1;
                                        else if (a1[i][j]==0)
                                                a2[i][j]=0;

                                }//end of iteration J
                        }//end of iteration I
                        #pragma omp barrier
                        #pragma omp single
                                {

                                        temp=a1;
                                        a1=a2;
                                        a2=temp;
                                }

                        #pragma omp barrier
                        }//end of iteration L

        }//end of paraller region
        gettimeofday(&tim,NULL);
         end=tim.tv_sec+(tim.tv_usec/1000000.0);
         printf("\nTime Elapsed:%.6lf\n",end-start);
        printf("all ok\n");
        return 0; }
#定义第1000+2行
#定义列1000+2整数;内部(*温度)[Col];int(*a1)[Col];int(*a2)[Col];
int main(){
int i,j,l,和;
int array1[行][Col],array2[行][Col];
结构时间间隔;
struct tm*tm;
双起点,双终点;
int-st,en;

对于(i=0;i您必须记住的一点是,您是在共享内存体系结构上执行此操作的。您尝试并行执行的加载/存储越多,您就越有可能遇到内存访问方面的争用,这是一个相对缓慢的操作。因此,在我的经验中,在典型应用程序中,不要从更多的操作中获益不超过6个核。(这是一个轶事,我可以深入了解很多细节,但我不想打字。我只想说,对这些数字有点保留)

如果可能,尽量减少对共享资源的访问,看看这对您的性能有什么影响。否则,请针对您得到的资源进行优化,并记住以下几点:

向一个问题扔更多的内核并不意味着它会更快。就像税收一样,当内核的数量开始影响程序的最大性能时,会有一个曲线。找到“最佳点”,并使用它。

你写的

以上时间是我使用 pthreads。当我使用openmp时 它们较小,但遵循相同的规则 模式

恭喜你,你已经发现了所有并行程序都遵循的模式!如果你将执行时间与处理器数量进行对比,曲线最终会变平并开始上升;你达到了一个点,即添加更多处理器会减慢速度

有趣的问题是,您可以使用多少处理器,这取决于许多因素。@jer指出了影响共享内存计算机上程序可伸缩性的一些因素。其他因素,主要是通信与计算的比率,确保性能的形状在分布式内存计算机上,曲线也将是相同的

在测量程序的并行可伸缩性时,另一个很重要的因素是您使用的问题大小。当您尝试使用1414 x 1414单元格的网格时,性能曲线会如何变化?我预计曲线将低于1000 x 1000单元格的问题曲线,稍后会变平


进一步阅读谷歌的阿姆达尔定律和古斯塔夫森定律。

可能是因为你的系统管理员控制着你可以同时执行多少个线程,或者你可以运行多少个内核。我不知道在系统管理员级别上是否可行,但可以肯定地告诉一个进程

或者,您的算法可能使用二级缓存的效果很差。当一个线程正在执行耗时较长的操作,而另一个线程没有执行时,超线程或任何他们称之为超线程的方法现在效果最好。访问不在二级缓存中的内存很慢,线程在等待时会暂停。这只是ti在单核上运行多个线程的方法来自。四核内存总线可能允许每个核同时访问一些ram,但不允许每个核中的每个线程。如果两个线程都使用ram,那么它们基本上是按顺序运行的。因此,这可能就是4的来源


您可以查看是否可以更改循环,使其在连续RAM上运行。如果您将问题分解为适合二级缓存的小块数据,并对这些块进行迭代,则可能会得到8x。如果您搜索“英特尔机器语言程序员指南”以了解其最新处理器,他们会讨论这些问题。

是的,我知道存在数据依赖关系,但是(解决它们超出了g