附录 A. 减少测量噪声(Reducing Measurement Noise)

以下是一些示例功能,它们可能导致性能测量的不确定性增加。有关完整讨论,请参见 [@sec:secFairExperiments]。

动态频率缩放(Dynamic Frequency Scaling)

动态频率缩放 (DFS): https://en.wikipedia.org/wiki/Dynamic_frequency_scaling11 是一种通过在运行要求苛刻任务时自动提高 CPU 运行频率来提升系统性能的技术。例如,英特尔 CPU 具有名为 睿频加速: https://en.wikipedia.org/wiki/Intel_Turbo_Boost1 的 DFS 实现功能,AMD CPU 则采用 Turbo Core: https://en.wikipedia.org/wiki/AMD_Turbo_Core2 功能。

以下示例展示了睿频加速对在 Intel® Core™ i5-8259U 上运行单线程工作负载的影响:

# 睿频加速启用
$ cat /sys/devices/system/cpu/intel_pstate/no_turbo
0
$ perf stat -e task-clock,cycles -- ./a.exe 
    11984.691958  task-clock (msec) #    1.000 CPUs utilized
  32,427,294,227  cycles            #    2.706 GHz
      11.989164338 seconds time elapsed

# 睿频加速禁用
$ echo 1 | sudo tee /sys/devices/system/cpu/intel_pstate/no_turbo
1
$ perf stat -e task-clock,cycles -- ./a.exe 
    13055.200832  task-clock (msec) #    0.993 CPUs utilized
  29,946,969,255  cycles            #    2.294 GHz
      13.142983989 seconds time elapsed

当睿频加速启用时,平均频率明显更高。

DFS 可以永久地在 BIOS 中禁用。3 要在 Linux 系统上以编程方式禁用 DFS 功能,您需要 root 权限。下面是如何实现这一点:

# 英特尔
echo 1 > /sys/devices/system/cpu/intel_pstate/no_turbo
# AMD
echo 0 > /sys/devices/system/cpu/cpufreq/boost

同时多线程(Simultaneous Multithreading)

现代 CPU 内核通常采用 同时多线程 (SMT): https://en.wikipedia.org/wiki/Simultaneous_multithreading4 方式制造。这意味着在一个物理内核中,您可以同时执行两个线程。通常,体系结构状态: https://en.wikipedia.org/wiki/Architectural_state5 会被复制,但执行资源(ALU、缓存等)不会。这意味着如果我们在同一个内核上以“同时”方式运行两个独立的进程(在不同的线程中),它们会相互争夺资源,例如缓存空间。

SMT 可以永久地在 BIOS 中禁用。6 要在 Linux 系统上以编程方式禁用 SMT,您需要 root 权限。下面是如何在每个内核中关闭一个兄弟线程:

echo 0 > /sys/devices/system/cpu/cpuX/online

可以在以下文件中找到 CPU 线程的兄弟对:

/sys/devices/system/cpu/cpuN/topology/thread_siblings_list

例如,在具有 4 个内核和 8 个线程的 Intel® Core™ i5-8259U 上:

# 所有 8 个硬件线程均已启用:
$ lscpu
...
CPU(s):              8
On-line CPU(s) list: 0-7
...
$ cat /sys/devices/system/cpu/cpu0/topology/thread_siblings_list
0,4
$ cat /sys/devices/system/cpu/cpu1/topology/thread_siblings_list
1,5
$ cat /sys/devices/system/cpu/cpu2/topology/thread_siblings_list
2,6
$ cat /sys/devices/system/cpu/cpu3/topology/thread_siblings_list
3,7

# 在内核 0 上禁用 SMT
$ echo 0 | sudo tee /sys/devices/system/cpu/cpu4/online
0
$ lscpu
CPU(s):               8
On-line CPU(s) list:  0-3,5-7
Off-line CPU(s) list: 4
...
$ cat /sys/devices/system/cpu/cpu0/topology/thread_siblings_list
0

缩放调速器(Scaling Governor)

Linux内核可以控制 CPU 频率用于不同的目的。其中一个目的是节能,在这种情况下,Linux内核内部的调速器7 可以决定降低 CPU 运行频率。对于性能测量,建议将调速器策略设置为“性能”,以避免低于标称时钟频率。下面是如何将其设置为所有内核:

for i in /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor
do
  echo performance > $i
done

CPU 亲和性(CPU Affinity)

处理器亲和性: https://en.wikipedia.org/wiki/Processor_affinity8 允许将进程绑定到特定 CPU 内核。在 Linux 中,可以使用 taskset: https://linux.die.net/man/1/taskset9 工具实现这一点。这里

# 无亲和性
$ perf stat -e context-switches,cpu-migrations -r 10 -- a.exe
               151      context-switches
                10      cpu-migrations

# 进程绑定到 CPU0
$ perf stat -e context-switches,cpu-migrations -r 10 -- taskset -c 0 a.exe 
               102      context-switches
                 0      cpu-migrations

请注意,cpu-migrations 的数量变为 0,即进程永远不会离开 core0

或者,您可以使用 cset: https://github.com/lpechacek/cpuset10 工具仅为要基准测试的程序预留 CPU。如果使用 Linux perf,请至少保留两个内核,以便 perf 在一个内核上运行,您的程序在另一个内核上运行。以下命令将从 N1 和 N2 中移动所有线程(-k on 表示即使内核线程也会被移动出去):

$ cset shield -c N1,N2 -k on

以下命令将在隔离的 CPU 上运行 -- 后面的命令:

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

进程优先级(Process Priority)

在 Linux 中,可以使用 nice 工具提高进程优先级。通过提高优先级,进程可以获得更多 CPU 时间,并且 Linux 调度器会比具有正常优先级的进程更青睐它。优先级范围从 -20(最高优先级值)到 19(最低优先级值),默认值为 0

请注意在上一个示例中,基准测试进程的执行被操作系统中断超过 100 次。如果我们通过使用 sudo nice -n -N 运行基准测试来提高进程优先级:

$ perf stat -r 10 -- sudo nice -n -5 taskset -c 1 a.exe
    0   context-switches
    0   cpu-migrations

请注意,上下文切换的数量变为 0,因此该进程不间断地接收所有计算时间。

文件系统缓存(Filesystem Cache)

通常,会分配一部分主内存来缓存文件系统内容,包括各种数据。这减少了应用程序访问磁盘的次数。以下示例说明了文件系统缓存如何影响简单 git status 命令的运行时间:

# 清空文件系统缓存
$ echo 3 | sudo tee /proc/sys/vm/drop_caches && sync && time -p git status
real 2,57
# 预热文件系统缓存
$ time -p git status
real 0,40

可以通过运行以下两个命令清除当前的文件系统缓存:

$ echo 3 | sudo tee /proc/sys/vm/drop_caches
$ sync

或者,您可以进行一次干运行以预热文件系统缓存,并将其排除在测量之外。此干运行可以与基准测试输出的验证结合使用。

1. 英特尔睿频加速 - https://en.wikipedia.org/wiki/Intel_Turbo_Boost.
2. AMD Turbo Core - https://en.wikipedia.org/wiki/AMD_Turbo_Core.
3. 英特尔睿频加速常见问题解答 - https://www.intel.com/content/www/us/en/support/articles/000007359/processors/intel-core-processors.html.
4. SMT - https://en.wikipedia.org/wiki/Simultaneous_multithreading.
5. 体系结构状态 - https://en.wikipedia.org/wiki/Architectural_state.
6. “如何禁用超线程” - https://www.pcmag.com/article/314585/how-to-disable-hyperthreading.
7. Linux CPU 频率调节器文档:https://www.kernel.org/doc/Documentation/cpu-freq/governors.txt.
8. 处理器关联性 - https://en.wikipedia.org/wiki/Processor_affinity.
9. taskset 手册 - https://linux.die.net/man/1/taskset.
10. cpuset 手册 - https://github.com/lpechacek/cpuset.
11. 动态频率缩放 - https://en.wikipedia.org/wiki/Dynamic_frequency_scaling.

results matching ""

    No results matching ""