{"id":4213,"date":"2020-08-31T07:00:38","date_gmt":"2020-08-30T22:00:38","guid":{"rendered":"https:\/\/glandium.org\/blog\/?p=4213"},"modified":"2023-08-30T07:43:43","modified_gmt":"2023-08-29T22:43:43","slug":"linux-disabling-cpu-turbo-cores-and-threads-without-rebooting","status":"publish","type":"post","link":"https:\/\/glandium.org\/blog\/?p=4213","title":{"rendered":"[Linux] Disabling CPU turbo, cores and threads without rebooting"},"content":{"rendered":"<p>[Disclaimer: this has been sitting as a draft for close to three months ; I forgot to publish it, this is now finally done.]<\/p>\n<p>In my <a href=\"\/blog\/?p=4117\">previous blog post<\/a>, I built Firefox in a multiple different number of configurations where I'd disable the CPU turbo, some of its cores or some of its threads. That is something that was traditionally done via the BIOS, but rebooting between each attempt is not really a great experience.<\/p>\n<p>Fortunately, the Linux kernel provides a large number of knobs that allow this at runtime.<\/p>\n<h1>Turbo<\/h1>\n<p>This is the most straightforward:<\/p>\n<pre><code>$ echo 0 &gt; \/sys\/devices\/system\/cpu\/cpufreq\/boost\n<\/code><\/pre>\n<p>Re-enable with<\/p>\n<pre><code>$ echo 1 &gt; \/sys\/devices\/system\/cpu\/cpufreq\/boost\n<\/code><\/pre>\n<h1>CPU frequency throttling<\/h1>\n<p>Even though I haven't mentioned it, I might as well add this briefly. There are many knobs to tweak frequency throttling, but assuming your goal is to disable throttling and set the CPU frequency to its fastest non-Turbo frequency, this is how you do it:<\/p>\n<pre><code>$ echo performance &gt; \/sys\/devices\/system\/cpu\/cpu<b>$n<\/b>\/cpufreq\/scaling_governor\n<\/code><\/pre>\n<p>where <em>$n<\/em> is the id of the core you want to do that for, so if you want to do that for all the cores, you need to do that for <code>cpu0<\/code>, <code>cpu1<\/code>, etc.<\/p>\n<p>Re-enable with:<\/p>\n<pre><code>$ echo ondemand &gt; \/sys\/devices\/system\/cpu\/cpu<b>$n<\/b>\/cpufreq\/scaling_governor\n<\/code><\/pre>\n<p>(assuming this was the value before you changed it ; <code>ondemand<\/code> is usually the default)<\/p>\n<h1>Cores and Threads<\/h1>\n<p>This one requires some attention, because you cannot assume anything about the CPU numbers. The first thing you want to do is to check those CPU numbers. You can do so by looking at the <code>physical id<\/code> and <code>core id<\/code> fields in <code>\/proc\/cpuinfo<\/code>, but the output from <code>lscpu --extended<\/code> is more convenient, and looks like the following:<\/p>\n<pre><code>CPU NODE SOCKET CORE L1d:L1i:L2:L3 ONLINE MAXMHZ    MINMHZ\n0   0    0      0    0:0:0:0       yes    3700.0000 2200.0000\n1   0    0      1    1:1:1:0       yes    3700.0000 2200.0000\n2   0    0      2    2:2:2:0       yes    3700.0000 2200.0000\n3   0    0      3    3:3:3:0       yes    3700.0000 2200.0000\n4   0    0      4    4:4:4:1       yes    3700.0000 2200.0000\n5   0    0      5    5:5:5:1       yes    3700.0000 2200.0000\n6   0    0      6    6:6:6:1       yes    3700.0000 2200.0000\n7   0    0      7    7:7:7:1       yes    3700.0000 2200.0000\n(...)\n32  0    0      0    0:0:0:0       yes    3700.0000 2200.0000\n33  0    0      1    1:1:1:0       yes    3700.0000 2200.0000\n34  0    0      2    2:2:2:0       yes    3700.0000 2200.0000\n35  0    0      3    3:3:3:0       yes    3700.0000 2200.0000\n36  0    0      4    4:4:4:1       yes    3700.0000 2200.0000\n37  0    0      5    5:5:5:1       yes    3700.0000 2200.0000\n38  0    0      6    6:6:6:1       yes    3700.0000 2200.0000\n39  0    0      7    7:7:7:1       yes    3700.0000 2200.0000\n(...)<\/code><\/pre>\n<p>Now, this output is actually the ideal case, where pairs of CPUs (virtual cores) on the same physical core are always <em>n, n+32<\/em>, but I've had them be pseudo-randomly spread in the past, so be careful.<\/p>\n<p>To turn off a core, you want to turn off all the CPUs with the same CORE identifier. To turn off a thread (virtual core), you want to turn off one CPU. On machines with multiple sockets, you can also look at the SOCKET column.<\/p>\n<p>Turning off one CPU is done with:<\/p>\n<pre><code>$ echo 0 &gt; \/sys\/devices\/system\/cpu\/cpu<b>$n<\/b>\/online\n<\/code><\/pre>\n<p>Re-enable with:<\/p>\n<pre><code>$ echo 1 &gt; \/sys\/devices\/system\/cpu\/cpu<b>$n<\/b>\/online\n<\/code><\/pre>\n<h1>Extra: CPU sets<\/h1>\n<p>CPU sets are a feature of Linux's cgroups. They allow to restrict groups of processes to a set of cores.<br \/>\nThe first step is to create a group like so:<\/p>\n<pre><code>$ mkdir \/sys\/fs\/cgroup\/cpuset\/mygroup<\/code><\/pre>\n<p>Please note you may already have existing groups, and you may want to create subgroups. You can do so by creating subdirectories.<\/p>\n<p>Then you can configure on which CPUs\/cores\/threads you want processes in this group to run on:<\/p>\n<pre><code>$ echo 0-7,16-23 &gt; \/sys\/fs\/cgroup\/cpuset\/mygroup\/cpuset.cpus<\/code><\/pre>\n<p>The value you write in this file is a comma-separated list of CPU\/core\/thread numbers or ranges. <code>0-3<\/code> is the range for CPU\/core\/thread 0 to 3 and is thus equivalent to <code>0,1,2,3<\/code>. The numbers correspond to <code>\/proc\/cpuinfo<\/code> or the output from <code>lscpu<\/code> as mentioned above.<\/p>\n<p>There are also memory aspects to CPU sets, that I won't detail here (because I don't have a machine with multiple memory nodes), but you can start with:<\/p>\n<pre><code>$ cat \/sys\/fs\/cgroup\/cpuset\/cpuset.mems &gt; \/sys\/fs\/cgroup\/cpuset\/mygroup\/cpuset.mems<\/code><\/pre>\n<p>Now you're ready to assign processes to this group:<\/p>\n<pre><code>$ echo $pid &gt;&gt; \/sys\/fs\/cgroup\/cpuset\/mygroup\/tasks<\/code><\/pre>\n<p>There are a number of tweaks you can do to this setup, I invite you to check out the <code>cpuset(7)<\/code> manual page.<\/p>\n<p>Disabling a group is a little involved. First you need to move the processes to a different group:<\/p>\n<pre><code>$ while read pid; do echo $pid &gt; \/sys\/fs\/cgroup\/cpuset\/tasks; done &lt; \/sys\/fs\/cgroup\/cpuset\/mygroup\/tasks<\/code><\/pre>\n<p>Then deassociate CPU and memory nodes:<\/p>\n<pre><code>$ &gt; \/sys\/fs\/cgroup\/cpuset\/mygroup\/cpuset.cpus\n$ &gt; \/sys\/fs\/cgroup\/cpuset\/mygroup\/cpuset.mems<\/code><\/pre>\n<p>And finally remove the group:<\/p>\n<pre><code>$ rmdir \/sys\/fs\/cgroup\/cpuset\/mygroup<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>[Disclaimer: this has been sitting as a draft for close to three months ; I forgot to publish it, this is now finally done.] In my previous blog post, I built Firefox in a multiple different number of configurations where I&#8217;d disable the CPU turbo, some of its cores or some of its threads. That [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5,25],"tags":[23],"class_list":["post-4213","post","type-post","status-publish","format-standard","hentry","category-pdo","category-planet-mozilla","tag-en"],"_links":{"self":[{"href":"https:\/\/glandium.org\/blog\/index.php?rest_route=\/wp\/v2\/posts\/4213","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/glandium.org\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/glandium.org\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/glandium.org\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/glandium.org\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=4213"}],"version-history":[{"count":14,"href":"https:\/\/glandium.org\/blog\/index.php?rest_route=\/wp\/v2\/posts\/4213\/revisions"}],"predecessor-version":[{"id":4315,"href":"https:\/\/glandium.org\/blog\/index.php?rest_route=\/wp\/v2\/posts\/4213\/revisions\/4315"}],"wp:attachment":[{"href":"https:\/\/glandium.org\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=4213"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/glandium.org\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=4213"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/glandium.org\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=4213"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}