zoukankan      html  css  js  c++  java
  • Xeon Phi 《协处理器高性能编程指南》随书代码整理 part 4

    ▶ 第五章,几个优化

    ● 代码

     1 #include <stdio.h>
     2 #include <stdlib.h>
     3 #include <math.h>
     4 
     5 #define S       1024*32
     6 #define T       float
     7 #define ITER    1000
     8 #define VLEN    16
     9 
    10 __declspec(noinline) void scalar(T *A, T *B, T *C, T k)     // 标量型
    11 {
    12     __assume_aligned(A, 64);                // 声明数组对齐到 512 bit
    13     __assume_aligned(B, 64);
    14     __assume_aligned(C, 64);
    15     for (int i = 0; i < S; i++)
    16     {
    17         T tmp = A[i] * k + B[i];
    18         if (tmp > 0.5f)
    19             tmp *= sin(B[i]);
    20         C[i] = tmp;
    21     }   
    22 }
    23 
    24 __declspec(noinline) void shortVector(T *A, T *B, T *C, T k)// 短向量型
    25 {
    26     __assume_aligned(A, 64);
    27     __assume_aligned(B, 64);
    28     __assume_aligned(C, 64);
    29     for (int i = 0; i < S; i+=VLEN)
    30     {
    31         T tmp[VLEN];
    32         tmp[:]= A[i:VLEN] * k + B[i:VLEN];  // Cilk 的 tmp[起点:长度] 作引用
    33         if (tmp[:] > 0.5f)
    34             tmp[:] *= sin(B[i:VLEN]);
    35         C[i:VLEN] = tmp[:];
    36     }
    37 }
    38 
    39 int main()
    40 {
    41     volatile __int64 start, time1, time2;
    42     T ref_result, short_result;    
    43     const float k = 0.5;
    44     
    45     T *A, *B, *C;                                   // 声明并定义对齐的数组或数组指针
    46     posix_memalign((void **)&A, 64, sizeof(T)*S);
    47     posix_memalign((void **)&B, 64, sizeof(T)*S);
    48     posix_memalign((void **)&C, 64, sizeof(T)*S);
    49     //__declspec(align(64)) T A[S], B[S], C[S];     // 等价的声明方式
    50         
    51     A[0:S] = __sec_implicit_index(0);               // 数组赋值为 {0, 1, 2, ...}
    52     B[0:S] = __sec_implicit_index(0);
    53     C[0:S] = 0;
    54     //for(int i=0;i<S;i++)                          // 等价的复制方法
    55     //   A[i] = B[i] = i, C[i] = 0;
    56 
    57     //for(int i=0;i<10;i++)
    58     //    printf("%f, ", A[i]);
    59     //printf("
    ");
    60     //for(int i=0;i<10;i++)
    61     //    printf("%f, ", B[i]);
    62     //printf("
    ");
    63     
    64     start = __rdtsc();                              // 计时器,计算 CPU 的tick 数
    65     for (int i = 0; i < ITER; i++)    
    66         scalar(A, B, C, k);
    67     time1 = __rdtsc() - start;
    68     //for(int i=0;i<10;i++)
    69     //    printf("%f, ", C[i]);
    70     //printf("
    ");    
    71     ref_result = __sec_reduce_add(C[0:S]);          // 规约加,用于比较结果是否正确
    72 
    73     start = __rdtsc();
    74     for (int i = 0; i < ITER; i++)       
    75         shortVector(A, B, C, k);       
    76     time2 = __rdtsc() - start;
    77     //for(int i=0;i<10;i++)
    78     //    printf("%f, ", C[i]);
    79     //printf("
    ");
    80     short_result = __sec_reduce_add(C[0:S]);
    81     
    82     printf("ref:	%f, %Id CPU tick
    short:	%f, %Id CPU tick
    ", ref_result, time1, short_result, time2);
    83     return 0;
    84 }

    ● 输出结果。O0 优化,XeonPhi 上 CPU tick,较少,尤其是 shortVector 优化效果明显,但是 O3 优化 XeonPhi 更差,甚至比自身 O0 还差

    [cuan@server3145 XeonPhi]$ icc kk.c -O0
    [cuan@server3145 XeonPhi]$ ./a.out 
    ref:      -39578.562500, 1514650782 CPU tick
    short:    -39578.562500, 1802072334 CPU tick
    [cuan@server3145 XeonPhi]$ icc -mmic kk.c -O0
    [cuan@server3145 XeonPhi]$ scp a.out cuan@mic0:/home/cuan
    cuan@mic0's password: 
    a.out                                                       100%   33KB  33.5KB/s   00:00    
    [cuan@server3145 XeonPhi]$ ssh cuan@mic0
    cuan@mic0's password: 
    [cuan@server3145-mic0 ~]$ ./a.out
    ref:      -39578.562500, 1467023211 CPU tick
    short:    -39578.562500, 414319544 CPU tick
    
    [cuan@server3145 XeonPhi]$ icc kk.c -O3
    [cuan@server3145 XeonPhi]$ ./a.out
    ref:      -39578.617188, 387034332 CPU tick
    short:    -39578.617188, 395228084 CPU tick
    [cuan@server3145 XeonPhi]$ icc -mmic kk.c -O3
    [cuan@server3145 XeonPhi]$ scp a.out cuan@mic0:/home/cuan
    cuan@mic0's password: 
    a.out                                                       100%   90KB  90.2KB/s   00:00    
    [cuan@server3145 XeonPhi]$ ssh cuan@mic0
    cuan@mic0's password: 
    [cuan@server3145-mic0 ~]$ ./a.out
    ref:      -39578.429688, 638000619 CPU tick
    short:    -39578.429688, 633708861 CPU tick
  • 相关阅读:
    【P000-004】交易费计算系统,功能类规划
    【P000-003】交易费计算系统,从股票信息网络接口获取信息
    ASP页面的执行顺序
    Python ImportError: DLL load failed: %1 不是有效的 Win32 应用程序
    VSCode运行已有代码
    WPF MVVM-TreeView数据源添加了节点,UI没有刷新
    MapGIS二次开发注意事项
    把echarts嵌入winform窗口注意事项
    host is not allowed to connect mysql解决方法
    SqlDbx连接Oracle数据库
  • 原文地址:https://www.cnblogs.com/cuancuancuanhao/p/10407972.html
Copyright © 2011-2022 走看看