2010-07-25 50 views
1

我在我的大学的服务器上运行了一个程序,该程序有4个双核AMD Opteron(tm)处理器2210 HE和O.S.是Linux版本2.6.27.25-78.2.56.fc9.x86_64。我的程序实现了Conways Game of Life,它使用pthreads和openmp运行。我使用1-8个线程使用getimeofday()函数对程序的并行部分进行了定时。但时机似乎并不正确。我得到最大的时间使用1个线程(如预期),然后时间变得更小。但我得到的最小时间是当我使用4个线程。在具有4个双核Cpu的服务器上使用1-8个线程的程序定时问题?

这里是一个例子,当我使用数组1000x1000。使用2个螺纹〜4,73秒,使用3〜3.64秒,使用4〜2.99秒,使用5〜4,19秒,使用6〜3.84,使用7〜3.62秒, 3.34,用8〜3.12。

上述时间是当我使用pthreads。当我使用openmp的时机较小,但遵循相同的模式。

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

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

该程序实现了正确的生命游戏,都使用pthreads和openmp,我只是不知道为什么时间就像我发布的例子。所以最后,我的问题是:

1)系统中可以同时运行的线程数取决于cpus的内核?它只依赖于cpus,尽管每个cpu都有多个内核?它取决于以前的所有操作系统?

2)它是否与我将1000x1000数组分配给线程数的方式有关?但是如果我做了那么openmp代码不会给出相同的时间模式?

3)什么原因我可能会得到这样的定时?

请原谅我的英语我来自欧洲... thnx在advanse。

编辑: 这是我使用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; } 

的时间设置与OpenMP代码

7双核心CPU 使用1〜螺纹秒7.72,使用a)系统2个螺纹〜4,53秒,使用3根螺纹〜3,64秒,使用4根螺纹〜2,24秒,使用5〜2,02秒,使用6〜1,78秒,使用7〜1,59秒,使用8〜1,44秒

b)带有4个双核CPU的系统 使用1个线程〜9,06秒,使用2个螺纹~4,86秒,使用3个螺纹~3.49秒,使用4个螺纹~2.61秒,使用5〜3,98秒,使用6〜3,53秒,使用7〜3秒, 48秒,使用8〜3,32秒

以上是我得到的时间。

回答

0

你必须记住的一件事是你正在共享内存体系结构上这样做。您试图并行执行的加载/存储越多,您就越有可能在内存访问方面争夺竞争对手,这是一个相对较慢的操作。所以在我的经验中的典型应用中,不能从6个内核中受益。 (这是一个轶事,我可以进入很多细节,但我不喜欢打字,只要说一句,用一粒盐来记下这些数字)。

试着尽可能减少对共享资源的访问,看看对你的性能有什么影响。否则,请优化所得结果,并记住:

在问题中投掷更多内核并不意味着它会更快。与税收一样,核心数量何时开始变得不利于收集程序中最高的性能。找到那个“甜蜜点”,并使用它。

+0

你好,thanx为答案。是的,我明白有数据依赖关系,但(解决它们超出了我的程序的目标)代码是这样的,当我在系统上测试它与4双核cpus(所以8核心)和系统有7双核Cpus的数据依赖性和缓存抖动和更新策略是相同的,每个缓存大小并没有改变。但是对于具有7个双核CPU的系统,我得到了我期望的时序,但是与其他具有8个内核的系统(并且我使用的线程的最大数量仍然是8)相比,当我使用4个线程时最小的执行时间。 – stois21 2010-07-26 16:16:33

0

你写

以上时序是当我使用 并行线程。当我使用openmp的时机 较小,但遵循相同的 模式。

恭喜你,你已经发现了所有并行程序遵循的模式!如果您根据处理器数量绘制执行时间,则曲线最终变平并开始上升;您达到了添加更多处理器会降低速度的问题。

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

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

欲了解更多谷歌阿姆达尔定律古斯塔夫森定律

+0

Hello和thanx的答案,所以即使一个系统有8个内核,并且我使用的线程的最大数量是8,它的逻辑是我得到的最小执行时间只有4个线程? 当我测试我的代码,有14个内核,你可以在我的编辑后看到的时机是什么会有人从14核心系统希望当您使用的线程的最大数量是8 – stois21 2010-07-26 16:27:18

+0

是,没有在系统上你所报告的是一个惊喜。我会很失望,如果我创建了一个程序,它最小化的执行时间只有4个8个核的,但并不感到惊讶。你是否尝试过运行更大的问题? – 2010-07-26 16:30:43

+0

我试过的最大尺寸的数组是1000x1000,当我尝试了更大的东西时,它没有编译。这样可以为有因调度,内存传输和系统架构的最小时间是4个线程的更新策略8个核系统。但是,只是通过增加CPU核心,我得到了我期望的时间?不是它一个事实,只是增加你没有硬件得到改良效果? – stois21 2010-07-26 17:41:03

0

可能是您的系统管理员正在控制您可以同时执行多少个线程或运行多少个核心。我不知道在系统管理员级别是否可行,但可以肯定的是可以告诉一个进程。

或者,您的算法可能是使用L2缓存差。当一个线程正在做一些需要很长时间而另一个线程不需要的东西时,超线程或者他们称之为的任何东西现在都是最好的。访问不在L2缓存中的内存是SLOW,并且线程在等待时会停顿。这只是在单个内核上运行多个线程的时间来自的一个例子。四核内存总线可能允许每个内核同时访问一些内存,但不是每个内核中的每个线程。如果两个线程都用于RAM,那么它们基本上是按顺序运行的。所以这可能是你的4来自哪里。

你可能会看看你是否可以改变你的循环,以便它们在连续的RAM上运行。如果您将问题分解为适合二级缓存的小块数据并遍历这些块,则可能会得到8倍。如果您为他们最新的处理器搜索英特尔机器语言程序员指南......他们会讨论这些问题。

相关问题