openacc的tile子句



  • 对于openacc手册的57页中给出的矩阵乘法的例子,使用例子下面给出的对k循环进行tile的方法,增大tile的大小时为什么程序性能不升反降?在LDM没装满的情况下不应该tile快越大性能越好吗?



  • @doublexnine 你应该确认一件事情.
    比方tile=32, 而循环长度只有1024, 那么只有32个从核在计算.



  • 此回复已被删除!


  • @夜深忽梦少年事 可是在这个例子中是对内层循环k添加的tile子句,64个从核在外层循环中就已经被全部分配了。在这个例子中将tile从2增加到8,实测花费的时间从0.35s增加到了0.41s。



  • @doublexnine 能把代码贴上来吗
    还有贴代码的时候前后加```, 不要截图, 看着闹心...



  • 此回复已被删除!


  • @夜深忽梦少年事

    1 #include<stdio.h>
      2 #include<stdlib.h>
      3 #include<sys/time.h>
      4 
      5 #define M 1024
      6 #define N 1024
      7 #define K 1024
      8 
      9 int A[M][N];
     10 int B[N][K];
     11 int C[M][K];
     12 
     13 double timer()
     14 {
     15     double t;
     16     struct timeval tv;
     17     gettimeofday(&tv, NULL);
     18     t = (double)tv.tv_sec * 1.0 + (double)tv.tv_usec * 1e-6;
     19     return t;
     20 }
     21 
     22 int main()
     23 {
     24     int i, j, k;
     25     double t1, t2;
     26     for(i = 0; i < M; i++)
     27         for(j = 0; j < N; j++)
     28             A[i][j] = i;
     29     for(i = 0; i < N; i++)
     30         for(j = 0; j < K; j++)
     31             B[i][j] = j;
    
    32     t1 = timer();
     33 
     34     #pragma acc parallel loop local(i, j, k) copyin(A, B) copy(C) \
     35     swapin(B(dimension order:1, 2))
     36     for(i = 0; i < M; i++)
     37     {
     38         #pragma acc loop tile(2) annotate(tilemask(C))
     39         for(k = 0; k < K; k++)
     40         {
     41             for(j = 0; j < N; j++)
     42             {
     43                 C[i][k] += A[i][j]*B[j][k];
     44             }
     45         }
     46     }
     47 
     48     t2 = timer();
     49     printf("matrixMul A[%d][%d] * B[%d][%d], use time:%.2f\n", M, N, N, K, t2 - t1);
     50 
     51     return 0;
     52 }
     53 
    


  • 8可能有点大.
    看上去变成一次拷进32K了...
    这样从核启动的延迟可能会变大一些...



  • @夜深忽梦少年事
    嗯嗯,知道了,谢谢老师。
    还有一个问题,我把openacc手册上的entire子句的例子测试了一下,发现entire修饰的数组并没有存到LDM内(通过编译器-ldmAnalyse获知的),是什么原因呢?

    int A[64], B[128][64];
    int main()
    {
        int i, j;
        #pragma acc parallel copyin(A) copyout(B) annotate(entire(A))
        {
        #pragma acc loop
        for(i = 0; i < 128; i++)
        {
            for(j = 0; j < 64; j++)
            B[i][j] = A[j] + i;
        }
        }
    }
    


  • ACC没有特别特别的了解...


登录后回复