ベンチマークのヒント

はじめに

パッチのベンチマークを行う場合、可能な限りノイズ発生源をすべて削減する必要があります。その方法は OS によって大きく異なります。

ノイズの低減は必要ですが、十分ではありません。測定のバイアスを除外できるわけではありません。たとえば、Mytkowicz、Diwan、Hauswith、Sweeney 著の「Obviously Wrong なことは何もしていないのに、間違いのあるデータが生成される!」(ASPLOS 2009)を参照してください。

全般

  • 高解像度のタイマーを使用します(例: Linux の場合 perf)。

  • ノイズを認識できるように、ベンチマークを何回も実行します。

  • 対象システムで可能な限り多くのプロセスまたはサービスを無効にします。

  • 周波数スケーリング、ターボブースト、アドレス空間のランダム化を無効にします(OS 固有のセクションを参照)。

  • OS がサポートしている場合は、静的にリンクします。これにより、動的ライブラリの読み込みによって発生する可能性がある変動を回避できます。これを行うには、-DLLVM_BUILD_STATIC=ON を cmake に渡します。

  • ストレージの使用を避けます。一部のシステムでは tmpfs を使用できます。プログラム、入力、出力を tmpfs に配置することで、実際のストレージシステムにアクセスするのを回避できます。ストレージシステムは非常に大きな変動を起こす可能性があります。

    マウントする方法(少なくとも Linux と FreeBSD の場合)

    mount -t tmpfs -o size=<XX>g none dir_to_mount
    

Linux

  • アドレス空間のランダム化を無効にします

    echo 0 > /proc/sys/kernel/randomize_va_space
    
  • scaling_governor を performance に設定します

    for i in /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor
    do
      echo performance > $i
    done
    
  • ベンチマークを実行するプログラム専用に CPU を予約するには、https://github.com/lpechacek/cpuset を使用します。perf を使用している場合は、perf が 1 つのコア、プログラムが別の 1 つのコアで実行されるように、少なくとも 2 つのコアを空けてください

    cset shield -c N1,N2 -k on
    

    これにより、すべてのスレッドが N1 と N2 から移動されます。-k on は、カーネルスレッドでさえも移動されることを意味します。

  • ベンチマークに使用する CPU の SMT ペアを無効にします。CPU N のペアは /sys/devices/system/cpu/cpuN/topology/thread_siblings_list にあり、次のように無効にすることができます

    echo 0 > /sys/devices/system/cpu/cpuX/online
    
  • 次のコマンドでプログラムを実行します。

    cset shield --exec -- perf stat -r 10 <cmd>
    

    これにより、-- の後のコマンドが、分離された CPU で実行されます。特定の perf コマンドは <cmd> を 10 回実行し、統計を報告します。

これらを設定することで、perf の変動が 0.1% 未満になるはずです。

Linux Intel

  • ターボモードを無効にします

    echo 1 > /sys/devices/system/cpu/intel_pstate/no_turbo