0

我有一个简单的单线程应用程序,几乎可以进行纯处理

  1. 它使用两个相同大小的 int 缓冲区
  2. 它一个接一个地读取第一个缓冲区的所有值
    • 每个值都是第二个缓冲区中的随机索引
  3. 它读取第二个缓冲区中索引处的值
  4. 它将从第二个缓冲区获取的所有值相加
  5. 它完成了所有前面的步骤,变得越来越大
  6. 最后,我打印自愿和非自愿 CPU 上下文切换的次数

如果缓冲区的大小变得相当大,我的电脑开始变慢:为什么?我有 4 个带超线程的内核,所以剩下 3 个内核。只有一个是 100% 忙的。是因为我的进程几乎 100% 使用“RAM 总线”吗?

然后,我创建了一个专用于我的进程的 CPU 集(我的 CPU 集包含同一核心的两个 CPU 线程)

$ cat /sys/devices/system/cpu/cpu3/topology/core_id 
3
$ cat /sys/devices/system/cpu/cpu7/topology/core_id 
3

$ cset set -c 3,7 -s my_cpuset
$ cset set -l
cset: 
         Name       CPUs-X    MEMs-X Tasks Subs Path
 ------------ ---------- - ------- - ----- ---- ----------
         root        0-7 y       0 y   934    1 /
    my_cpuset        3,7 n       0 n     0    0 /my_cpuset

似乎我的 CPU 集上根本没有任何任务正在运行。我可以重新启动我的进程,并在它运行时启动:

$ taskset -c 7 ./TestCpuset # Here, I launch my process
...
$ ps -mo pid,tid,fname,user,psr -p 25244 # 25244 being the PID of my process
  PID   TID COMMAND  USER     PSR
25244     - TestCpus phil       -
    - 25244 -        phil       7

PSR = 7:我的进程在预期的 CPU 线程上运行良好。我希望它是唯一一个在它上面运行的,但最后,我的进程显示:

Number of voluntary context switch:   2
Number of involuntary context switch: 1231

如果我有非自愿的上下文切换,这意味着其他进程正在我的核心上运行:这怎么可能?我必须做什么才能使非自愿上下文切换次数 = 0?

最后一个问题:当我的进程运行时,如果我启动

$ cset set -l
cset: 
         Name       CPUs-X    MEMs-X Tasks Subs Path
 ------------ ---------- - ------- - ----- ---- ----------
         root        0-7 y       0 y  1031    1 /
    my_cpuset        3,7 n       0 n     0    0 /my_cpuset

我再次在我的 CPU 集上获得 0 个任务。但是我知道有一个进程在上面运行:好像一个任务不是一个进程?

4

1 回答 1

1

如果缓冲区的大小变得相当大,我的电脑开始变慢:为什么?我有 4 个带超线程的内核,所以剩下 3 个内核。只有一个是 100% 忙的。是因为我的进程几乎 100% 使用“RAM 总线”吗?

您达到了单线程应用程序的硬件性能限制,即您的程序分配到的单个 CPU 上的 100% CPU 时间。您的应用程序线程一次不会在多个 CPU 上运行(参考)

我必须做什么才能使非自愿上下文切换次数 = 0?

你不是在命令中缺少--cpu_exclusive选项吗?cset set

顺便说一句,如果你想实现更短的执行时间,我建议你做一个多线程应用程序,让操作系统和下面的硬件并行执行。将进程锁定到 CPU 集并阻止它进行上下文切换可能会降低操作系统性能并且不是可移植的解决方案。

于 2016-11-19T17:21:23.620 回答