hardware_concurrency#

Fully qualified name: carb::thread::hardware_concurrency

Defined in carb/thread/Util.h

inline unsigned carb::thread::hardware_concurrency() noexcept#

Similar to std::thread::hardware_concurrency(), but pays attention to docker cgroup config and CPU limits.

Docker allows a container’s CPU usage to be limited in two ways - CPU quotas and CPU sets. A CPU quota provides a ratio of core usage time versus the scheduling period. A CPU set explicitly lists which host CPU cores the container’s processes are allowed to run on. Both types of limits work together to provide an effective overall CPU usage limit.

When launching a container, Docker will respect the cgroup version that the host system is using. Currently cgroups have version 1 and 2, both effectively providing the same info for CPU usage limits, but specified in different ways. The cgroups are controlled through a mounted filesystem directory structure. There is always a root cgroup defined for the entire system located at /sys/fs/cgroup/. Other child cgroups an also be defined to further limit the resources available to specific processes. The main difference between the two versions is that the cgroup v1 interface is a hierarchical directory structure whereas v2 uses a simpler flat directory. Each version also has different filenames for some of the resource interface files.

For cgroup v1, the CPU set is defined in the following files:

  • /sys/fs/cgroup/cpuset/cpuset.cpus

  • /sys/fs/cgroup/cpuset/cpuset.effective_cpus

For cgroup v2, the CPU set is defined in the following files:

  • /sys/fs/cgroup/cpuset.cpus

  • /sys/fs/cgroup/cpuset.cpus.effective

For cgroup v1, the CPU quota is defined in the following files:

  • /sys/fs/cgroup/cpu/cpu.cfs_quota_us (CPU quota time in microseconds).

  • /sys/fs/cgroup/cpu/cpu.cfs_period_us (CPU scheduling period time in microseconds).

For cgroup v2, the CPU quota is defined in the following file (both the quota and period time values are specified in the same file with ‘quota’ being first and ‘period’ second. The ‘quota’ value may be max to indicate that there is no limiting):

  • /sys/fs/cgroup/cpu.max

When launching a container, docker allows both a CPU quota and a CPU set to be defined. Both are valid together or may be used separately to limit total CPU usage inside the container. The CPU set is defined using the --cpuset-cpus command line option and the CPU quota is defined using the --cpus command line option. Fractional CPU quotas are allowed and will be rounded up or down as needed here. A quota of a half or larger will round up to a full CPU core. It is possible to have an odd number reported by this function when a CPU quota is used.

Examples:

  • Docker --cpus="3.75" will produce 4 (rounds fractional up)

  • Docker --cpus="3.50" will produce 4 (rounds fractional up)

  • Docker --cpus="3.25" will produce 3 (rounds fractional down)

  • Docker --cpus="0.25" will produce 1 (minimum of 1)

  • Docker --cpuset-cpus="0-1,3" will produce 3 (cores 0, 1, and 3 are available).

  • Docker --cpuset-cpus="0-3" will produce 4 (cores 0, 1, 2, and 3 are available).

  • Docker --cpuset-cpus="0,5,7,9,15" will produce 5 (cores 0, 5, 7, 9, and 15).

  • Docker --cpuset-cpus="1" will produce 1 (only core 1 is available).

  • Docker --cpuset-cpus="0-3" --cpus="2.75" will produce 3 (the quota limits here)

  • Docker --cpuset-cpus="0-3" --cpus="4.75" will produce 4 (the CPU set limits here)

Returns:

The number of CPUs available on the current system or within the current container, if applicable.