假设是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
将返回联机处理器的数量,但不考虑隔离的核心数量。对于grepping /proc/cpuinfo
或lscpu
也是如此。
我研究了/proc/self
,但没有找到一种干净的方法。
1条答案
按热度按时间6uxekuva1#
您需要命令
nproc
:nproc
-打印可用的处理单元数关联掩码包含3个处理器的示例:
如果
nproc
由于某种原因不可用,我以前的答案可能会有用:taskset
命令用于设置或检索给定pid的运行进程的CPU关联taskset
的-p
选项表示:因此,您将得到一个十六进制数,其中包含进程的关联掩码。
现在,您需要执行popcount(计算
1
的二进制表示数)。然后,我们将该数字转换为二进制形式,然后计算
1
的个数。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来解决这个问题: