为什么我的超线程linux服务器上只有一半内核被加载?

我有一个服务器是12核心超线程系统,这意味着我有24个虚拟核心。

我在服务器上运行了24个进程,每个进程都在自己的端口上进行侦听,并且执行相同的操作,尽pipe来自不同的客户端和不同的请求。 这个过程是一个python脚本,它是在等待networking操作完成时使用gevent进行并发构build的。 top和htop使用大致相同的CPU和内存显示每个进程。 由于我正在运行与内核相同的进程数,因此我希望所有内核的加载大致相同。 但是,我看到只有一半的核心有任何实际的负载(其余显示最小的负载)。

对我来说更奇怪的是,它总是相同的核心,6-11和18-23。 更重要的是,我有三台相同的服务器在相同的负载下执行相同的操作,所有3台服务器都使用相同的内核。 有谁知道这是为什么?

以下是其中一台服务器的sar输出:

04:34:01 PM CPU %user %nice %system %iowait %steal %idle 04:35:01 PM all 18.67 0.00 3.65 0.01 0.00 77.68 04:35:01 PM 0 9.24 0.00 0.76 0.00 0.00 89.99 04:35:01 PM 1 3.16 0.00 0.55 0.00 0.00 96.30 04:35:01 PM 2 1.40 0.00 0.66 0.00 0.00 97.94 04:35:01 PM 3 0.46 0.00 0.12 0.00 0.00 99.42 04:35:01 PM 4 0.15 0.00 0.12 0.00 0.00 99.73 04:35:01 PM 5 0.35 0.00 0.81 0.00 0.00 98.84 04:35:01 PM 6 44.19 0.00 10.05 0.02 0.00 45.74 04:35:01 PM 7 43.99 0.00 10.84 0.02 0.00 45.15 04:35:01 PM 8 27.00 0.00 2.57 0.09 0.00 70.33 04:35:01 PM 9 40.91 0.00 9.02 0.02 0.00 50.06 04:35:01 PM 10 41.97 0.00 10.27 0.00 0.00 47.77 04:35:01 PM 11 33.52 0.00 5.26 0.02 0.00 61.21 04:35:01 PM 12 0.53 0.00 0.10 0.00 0.00 99.37 04:35:01 PM 13 0.32 0.00 0.08 0.00 0.00 99.60 04:35:01 PM 14 0.22 0.00 0.10 0.00 0.00 99.68 04:35:01 PM 15 0.13 0.00 0.10 0.00 0.00 99.77 04:35:01 PM 16 0.12 0.00 0.05 0.00 0.00 99.83 04:35:01 PM 17 0.13 0.00 0.30 0.00 0.00 99.57 04:35:01 PM 18 16.54 0.00 1.49 0.00 0.00 81.97 04:35:01 PM 19 36.16 0.00 5.85 0.02 0.00 57.98 04:35:01 PM 20 29.22 0.00 4.97 0.10 0.00 65.71 04:35:01 PM 21 32.86 0.00 5.25 0.02 0.00 61.87 04:35:01 PM 22 43.01 0.00 9.19 0.00 0.00 47.80 04:35:01 PM 23 39.63 0.00 8.61 0.02 0.00 51.74 

以下是其中一个内核的/ proc / cpuinfo的输出:

 processor : 23 vendor_id : GenuineIntel cpu family : 6 model : 44 model name : Intel(R) Xeon(R) CPU X5675 @ 3.07GHz stepping : 2 cpu MHz : 1600.000 cache size : 12288 KB physical id : 1 siblings : 12 core id : 10 cpu cores : 6 apicid : 53 initial apicid : 53 fpu : yes fpu_exception : yes cpuid level : 11 wp : yes flags : fpu vme de pse tsc msr pae mce cx8 apic mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon pebs bts rep_good xtopology nonstop_tsc aperfmperf pni dtes64 monitor ds_cpl vmx smx est tm2 ssse3 cx16 xtpr pdcm dca sse4_1 sse4_2 popcnt lahf_lm ida arat tpr_shadow vnmi flexpriority ept vpid bogomips : 6133.17 clflush size : 64 cache_alignment : 64 address sizes : 40 bits physical, 48 bits virtual power management: 

这些系统还有〜24GB的内存,其中不足4GB正在使用,并没有显示任何交换活动。 磁盘活动也很less,几乎所有这些服务器所做的都是networking绑定,每个约60-80MB / s,内外双吉比特以太网卡,绑定到一个单一的接口。

这是因为它是一个超线程服务器。 一半的CPU只是“虚拟”的。 所以Linux试图避免这些虚拟的CPU,专注于真正的CPU。

由于你的系统没有负载,你不能看到其他人将在更高的负载使用。 尝试一下,增加负载。 你会看到不同之处。

超线程核心不被视为完全有效的核心。 请记住,它们是虚拟内核,因此它们共享物理内核的一些资源。 超线程表面在高线程和并行化的过程中的好处,但不是在描述的用例中。 根据我的经验,超线程内核的性能好像是真实内核的30-40%,所以我倾向于保留重要的内核。 如果您希望一对一进程核心映射,那么最好将12个进程绑定到真实内核,或者通过禁用超线程或CPU屏蔽来完全避免虚拟内核。

你正在使用某种forms的CPU亲和性映射(taskset,cset),还是让Linux处理分配? 如果是这样,你所看到的就是调度程序最好的利用你的情况,更喜欢虚拟内核的真正核心。