假设 Linux,并假设当前 shell 的启动可能受到任务集的限制,我可以编写一些代码来获取当前进程关联性,如下所示
#include <vector>
#include <pthread.h>
#include <stdio.h>
int getNumberOfAvailableCores() {
pthread_t self = pthread_self();
cpu_set_t cpuset;
CPU_ZERO(&cpuset);
int res = ::pthread_getaffinity_np(self, sizeof(cpuset), &cpuset);
int num_cores = 0;
if ( res!=0 ) return -1;
for (int j = 0; j < CPU_SETSIZE; j++) {
if (CPU_ISSET(j, &cpuset)) ++num_cores;
}
return num_cores;
}
int main() {
int num_cores = getNumberOfAvailableCores();
printf( "%d\n", num_cores );
return 0;
}
https://godbolt.org/z/TxT67WWT6
但是在我什至没有安装编译器的机器上,有什么方法可以猜测可用内核的数量吗?
getconf _NPROCESSORS_ONLN
将返回在线处理器的数量,但不会考虑隔离的核心数量。与 grep /proc/cpuinfo
或 lscpu
相同。
我查看了 /proc/self
但找不到一个干净的方法来做到这一点。
最佳答案
您需要命令nproc
:
nproc
- 打印可用处理单元的数量
关联掩码包含 3 个处理器的示例:
$ taskset --cpu-list 0,2,4 bash
$ nproc
3
如果 nproc
由于某种原因不可用,我的旧答案可能会很有用:
The
taskset
command is used to set or retrieve the CPU affinity of a running process given its pid
taskset
的 -p
选项表示:
- 对现有 PID 进行操作,并且不启动新任务。
因此,您将获得一个带有进程亲和性掩码的十六进制数字。示例:
$ taskset -p $$
pid 1643922's current affinity mask: fff
现在,您想做 popcount (计算数字的二进制表示形式中 1
的数量)。
想法是将数字转换为二进制形式,然后计算 1
的数量。这是一句话:
taskset -p $$ | \
tr '[[:lower:]]' '[[:upper:]]' | \
sed -E 's/.*:\s*/ibase=16;obase=2;/' | bc | tr -d '0\n' | wc -c
tr '[[:lower:]]' '[[:upper:]]'
- 将taskset
的输出转换为大写(因为bc
需要大写的十六进制数字)。sed -E 's/.*:\s*/ibase=16;obase=2;/'
- 从taskset
中删除文本输出并替换它带有bc
的说明。ibase
是输入数字的基数(16 = 十六进制),obase
是我们想要输出的基数(2 = 二进制)。- 此时我们将得到
ibase=16;obase=2;FFF
- 此时我们将得到
bc
- 读取ibase=16;obase=2;FFF
并将FFF
打印为111111111111
<tr -d '0\n'
- 从bc
的输出中删除所有零和换行符wc -c
- 计算所有字符。
在我的例子中,亲和性掩码为 fff
,输出为 12
。
测试:我在这里启动一个具有 3 个可用处理器的子 shell,然后在该 shell 中使用上面的 oneliner 来解决这个问题:
$ taskset --cpu-list 0,2,4 bash
$ taskset -p $$ | \
> tr '[[:lower:]]' '[[:upper:]]' | \
> sed -E 's/.*:\s*/ibase=16;obase=2;/' | bc | tr -d '0\n' | wc -c
3
关于linux - 在不编写任何代码的情况下,是否有一个命令可以检索当前 shell 的亲和性中可用核心的数量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75688612/