2016-06-08 41 views
1

我正在做一些低延遲編程的實驗。我想消除上下文切換,並能夠可靠地測量延遲,而不會對性能造成太大影響。首先,我寫了一個程序,它要求1M次循環中的時間並打印統計信息(下面的代碼),因爲我想知道調用定時器的時間是多少。出人意料的是,輸出如下(微秒):儘管將線程綁定到特定的CPU核心,爲什麼會出現奇怪的時序結果?

Mean: 0.59, Min: 0.49, Max: 25.77 
Mean: 0.59, Min: 0.49, Max: 11.73 
Mean: 0.59, Min: 0.42, Max: 14.11 
Mean: 0.59, Min: 0.42, Max: 13.34 
Mean: 0.59, Min: 0.49, Max: 11.45 
Mean: 0.59, Min: 0.42, Max: 14.25 
Mean: 0.59, Min: 0.49, Max: 11.80 
Mean: 0.59, Min: 0.42, Max: 12.08 
Mean: 0.59, Min: 0.49, Max: 21.02 
Mean: 0.59, Min: 0.42, Max: 12.15 

正如你可以看到,雖然平均時間少於一微秒, 有高達20微秒的尖峯。儘管代碼運行在專用核上(親和力設置爲特定核心,而init進程的親和力設置爲一組其他核心),並且該機器上的超線程被禁用。試用了多個內核版本,包括搶先和RT,結果基本相同。

您能否解釋平均值和最大值之間的巨大差異?
問題在調用定時器,與進程隔離?

我也試圖與呼叫其他計時器 -
CLOCK_MONOTONIC, - -
- CLOCK_THREAD_CPUTIME_ID
CLOCK_PROCESS_CPUTIME_ID
- 和觀察到的模式是一樣的......

#include <time.h> 
#include <sched.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <stdint.h> 

#define min(a, b) ((a) < (b) ? (a) : (b)) 
#define max(a, b) ((a) > (b) ? (a) : (b)) 

uint64_t 
time_now() 
{ 
    struct timespec ts; 
    clock_gettime(CLOCK_REALTIME, &ts); 

    return ts.tv_sec * 1000000000 + ts.tv_nsec; 
} 

void 
set_affinity(int cpu) 
{ 
    cpu_set_t set; 
    CPU_ZERO(&set); 
    CPU_SET(cpu, &set); 

    if (sched_setaffinity(0, sizeof(set), &set)) 
    { 
      perror("sched_setaffinity"); 
    } 
} 


#define NUM 1000000 
#define LOOPS 10 

int 
main(int argc, char **argv) 
{ 
    set_affinity(3); 

    for (int loop = 0; loop < LOOPS; ++ loop) 
    { 
     uint64_t t_0 = time_now(); 

     uint64_t sum_val = 0; 
     uint64_t max_val = 0; 
     uint64_t min_val = uint64_t(-1); 

     for (int k = 0; k < NUM; ++ k) 
     { 
      uint64_t t_1 = time_now(); 
      uint64_t t_diff = t_1 - t_0; 

      sum_val += t_diff; 
      min_val = min(t_diff, min_val); 
      max_val = max(t_diff, max_val); 

      t_0 = t_1; 
     } 

     printf("Mean: %.2f, Min: %.2f, Max: %.2f\n", ((double)sum_val)/NUM/1000, ((double)min_val)/1000, ((double)max_val)/1000); 
    } 

    return 0; 
} 
+0

最好使用asm「rdtsc」指令進行精確時間測量 – eungenue

回答

0

兩個不可預測的來源會來自設備中斷和定時器。雖然您已設置用戶空間進程的關聯性,但設備中斷將會發生,並會影響您的進程。內核還會使用定時器來定期發出滴答聲,以便跟蹤時間。我會說這些將成爲你不可預測性的前兩個主要來源。用於核心彼此發信號的進程間中斷(IPI)將是另一箇中斷,但可能不會像前兩個那樣高。

相關問題