Те же инструкции с разными циклами процессора - PullRequest
0 голосов
/ 18 октября 2018

Я настраиваю программу на С ++, два разных ввода приводят к почти одинаковому числу или инструкциям, однако между циклами процессора есть большая разница.

Ниже приведена perf stat информация, это действительно странно.Кто-нибудь знает, что может привести к такой разнице во времени?

Статистика счетчика производительности для ./sai2 100000,C,98.700,60,98.695,0.2,0.0:

   2684.371940      task-clock (msec)         #    1.000 CPUs utilized          
            17      context-switches          #    0.006 K/sec                  
             1      cpu-migrations            #    0.000 K/sec                  
           921      page-faults               #    0.343 K/sec                  
 7,292,413,665      cycles                    #    2.717 GHz                    
11,267,827,416      instructions              #    1.55  insn per cycle         
   940,483,779      branches                  #  350.355 M/sec                  
       132,437      branch-misses             #    0.01% of all branches        

   2.685433574 seconds time elapsed

Статистика счетчика производительности для ./sai2 100000,P,98.700,60,98.695,0.2,0.0

  25698.831411      task-clock (msec)         #    1.000 CPUs utilized          
            72      context-switches          #    0.003 K/sec                  
            19      cpu-migrations            #    0.001 K/sec                  
           921      page-faults               #    0.036 K/sec                  
70,402,935,601      cycles                    #    2.740 GHz                    
10,418,026,021      instructions              #    0.15  insn per cycle         
   956,483,724      branches                  #   37.219 M/sec                  
       323,444      branch-misses             #    0.03% of all branches        

  25.702346518 seconds time elapsed

Что меня действительно смутило, так это то, что код с наибольшей стоимостью временипочти такие же.

// const double vector definitions
__m256d vec_1_p = _mm256_set1_pd(v_1_p_discount);
__m256d vec_p = _mm256_set1_pd(v_p_discount);
__m256d vec_tricky = _mm256_set_pd(tricky_3, tricky_2, tricky, 1);
__m256d vec_strike = _mm256_set1_pd(strike);

for (int m = m_stepNumber - 1; m > 0; m--) {
  double m_s_pointer = power_d / d;
  power_d = m_s_pointer;
  for (int n = 0; n < m; n += 4) {
    double *val = known + n;
    double *dest = to_calc + n;

    __m256d hold_0 = _mm256_load_pd(val);
    __m256d hold_1 = _mm256_loadu_pd(val+1);
    hold_0 = _mm256_mul_pd(hold_0, vec_1_p);
    hold_1 = _mm256_mul_pd(hold_1, vec_p);
    hold_0 = _mm256_add_pd(hold_0, hold_1);

    __m256d vec_tmp = _mm256_set1_pd(m_s_pointer);
    vec_tmp = _mm256_mul_pd(vec_tmp, vec_tricky);

    //vec_tmp = _mm256_sub_pd(vec_tmp, vec_strike);   this run in quick case
    //vec_tmp = _mm256_sub_pd(vec_strike, vec_tmp);   this run in slow case

    hold_0 = _mm256_max_pd(hold_0, vec_tmp);
    _mm256_store_pd(dest, hold_0);
    m_s_pointer *= tricky_4;
  }
  std::swap(known, to_calc);
}

Я использую perf record, чтобы увидеть тушеное мясо с овощами медленного случая, как показано ниже

    0.00 │520:┌─→vmulpd -0x8(%rdx),%ymm1,%ymm3
   41.48 │    │  add    $0x4,%ecx
    1.94 │    │  add    $0x20,%rdx
    0.52 │    │  vmovup -0x20(%rdx),%ymm0
    3.85 │    │  add    $0x20,%rsi
    0.31 │    │  vfmadd %ymm2,%ymm3,%ymm0
   42.73 │    │  vmovup -0x20(%rsi),%ymm3
    5.53 │    │  vmaxpd %ymm3,%ymm0,%ymm0
    2.77 │    │  vmovap %ymm0,-0x28(%rdx)
    0.86 │    │  cmp    %edi,%ecx 
         │    └──jle    520

, более быстрый случай

      3.43 │398:┌─→vmovup -0x8(%rdx),%ymm3
      9.18 │    │  add    $0x4,%ecx
      1.64 │    │  add    $0x20,%rdx
      5.44 │    │  vmovup -0x20(%rdx),%ymm0
     12.03 │    │  add    $0x20,%rsi
      2.32 │    │  vmulpd %ymm1,%ymm3,%ymm3
      7.28 │    │  vfmadd %ymm2,%ymm3,%ymm0
     16.77 │    │  vmovup -0x20(%rsi),%ymm3
     19.33 │    │  vmaxpd %ymm3,%ymm0,%ymm0
     15.83 │    │  vmovup %ymm0,-0x28(%rdx)
      6.70 │    │  cmp    %edi,%ecx
           │    └──jle    398
...