- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我想通过 sched_affinity
在多个 CPU 上设置亲和性,如下所示。
void
pin(pid_t t, int cpu)
{
cpu_set_t cpuset;
CPU_ZERO(&cpuset);
CPU_SET(cpu, &cpuset);
sched_setaffinity(t, sizeof(cpu_set_t), &cpuset);
}
我的环境是32核,其中有4个CPU,单CPU有8核。
我希望线程 0 ~ 7 运行在同一个 cpu 上,线程 8 ~ 15 运行在同一个 cpu 上,依此类推。
我想知道如何在 CPU_SET 中设置变量 cpu。
这被设置为线程 id,如果核心数分配为天真,即 cpu0 有第 0 个核心,第 1 个核心,第 2 个核心,...,而 cpu1 有第 8 个核心,第 9 个核心,...。
一方面,cpu设置为循环规则,如果核心数分配为循环规则,即cpu0有第0个核心,第4个核心,第8个核心,...,cpu1有第 1 个核心和第 5 个核心,...。
我应该设置可变cpu,朴素规则还是轮询规则?
最佳答案
在 Linux(和其他操作系统)下,程序员可以设置 CPU 亲和性,即内核可以将此进程调度到允许的 CPU。在 fork() 之后,进程继承父 CPU 亲和性。如果出于某种原因想要限制 CPU,这会非常方便。
例如一个可能会限制
一般来说,将进程/线程限制在某些内核或套接字上可能是有益的,以免它们被操作系统调度——最大化 L1/L2 缓存的好处(当固定到内核时)或 L3/LLC 缓存(固定到套接字时)。
关于您关于“线程分布”的问题:处理器开发引入了对称多线程 (SMT) 或超线程(英特尔称之为),每个物理核心引入了 2 个逻辑内核(例如英特尔至强)甚至 4 个逻辑内核(例如英特尔骑士登陆、IBM Power)。这些逻辑核心在上面的 cpuset 中也被表示为“CPU”。此外,一些处理器强加了 NUMA 域,其中从一个内核到它“自己的”内存的内存访问速度很快,而访问另一个 NUMA 域中的另一个内核内存则较慢......
所以,正如上面的一些评论所暗示的那样:这取决于!您的线程是否相互通信(通过共享内存),那么它们应该保持在同一个缓存中。您的线程是否使用相同的功能单元(例如 FPU),然后在同一物理内核(具有 2 个逻辑内核,即超线程)上调度两个线程可能会对性能产生不利影响。
要尝试,请找到以下代码:
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/param.h>
#include <sys/sysctl.h>
#include <pthread.h>
// The following is Linux-specific
#include <syscall.h> // For syscall to gettid()
#include <sched.h> // sched_[gs]etaffinity require _GNU_SOURCE
#define ERROR(t, e) do { \
const int __error = (e); \
fprintf (stderr, "ERROR: %s error:%d [%s] errno:%d [%s]\n", \
(t), __error, strerror(__error), errno, strerror(errno)); \
exit(__error); \
} while(0)
#ifndef MAX
#define MAX(a,b) ((a) > (b) ? (a) : (b))
#endif
#ifndef MIN
#define MIN(a,b) ((a) < (b) ? (a) : (b))
#endif
/* Local function definitions */
void print_schedaffinity(const char * text, const cpu_set_t cpuset, const int max_cpus);
void * thread_func(void * arg);
/* Local type definitions */
struct thread_data {
pthread_t thread;
int max_cpu;
int thread_num;
void * thread_work;
};
/* The highest value for CPU to be specified in cpuset in a call to
* sched_setaffinity -- otherwise, we get returned -1 and errno==EINVAL
*/
static int max_cpu_available = 0;
/* Local function declarations */
void print_schedaffinity(const char * text, const cpu_set_t cpuset, const int max_cpus) {
const int max = MIN(8*sizeof(cpu_set_t), max_cpus);
int i;
printf("PRINT CPU AFFINITY %s:\n", text);
printf("cpus:\t");
for (i = 0; i < max; i++) {
printf (" %3d", i);
if (i % 8 == 7)
printf(" | ");
}
printf("\nmask:\t");
for (i = 0; i < max; i++) {
if (CPU_ISSET(i, &cpuset))
printf (" X");
else
printf (" ");
if (i % 8 == 7)
printf(" | ");
}
printf("\n");
}
void * thread_func(void * arg) {
struct thread_data * thread_data = (struct thread_data *)arg;
const size_t sizeof_cpuset = sizeof(cpu_set_t);
char print_buffer[64];
cpu_set_t cpuset;
long tid;
int rc;
CPU_ZERO(&cpuset);
CPU_SET(thread_data->thread_num % max_cpu_available, &cpuset);
/* We set the affinity of the CALLING thread, aka 0 */
tid = syscall(SYS_gettid);
printf("PID:%ld tid:%ld thread_num:%d\n",
getpid(), tid, thread_data->thread_num);
rc = sched_setaffinity(0, sizeof_cpuset, &cpuset);
if (0 != rc)
ERROR("sched_setaffinity", rc);
/* Dooo SCHTUF now */
/* Somewhat sort the output... */
sleep (thread_data->thread_num);
snprintf (print_buffer, sizeof(print_buffer),
"in thread %d after sched_setaffinity", thread_data->thread_num);
print_schedaffinity(print_buffer, cpuset, 8);
return NULL;
}
int main (int argc, char * argv[])
{
const int NUM = 8;
const pid_t pid = getpid();
const size_t size_cpu_set = sizeof(cpu_set_t);
cpu_set_t cpuset;
int rc;
int i;
/* Get, and print the original CPU affinity setting (scheduling is not limited, i.e. all cores may run this PID) */
CPU_ZERO (&cpuset);
rc = sched_getaffinity(pid, size_cpu_set, &cpuset);
if (0 != rc)
ERROR("sched_getaffinity", rc);
print_schedaffinity("in main", cpuset, 8);
/* Search for the last / highest cpu being set -- claim, that this is the max cpu to be set, cough */
for (i = 0; i < 8 * size_cpu_set; i++) {
if (!CPU_ISSET(i, &cpuset)) {
max_cpu_available = i;
break;
}
}
/* Limit the process to the first core, only */
CPU_ZERO (&cpuset);
CPU_SET (0, &cpuset);
rc = sched_setaffinity (pid, size_cpu_set, &cpuset);
if (0 != rc)
ERROR("sched_setaffinity", rc);
print_schedaffinity("in main after sched_setaffinity", cpuset, 8);
/* Let's start NUM threads and have them limit their scheduling */
sleep(1);
struct thread_data * thread_data = (struct thread_data*)malloc(sizeof(struct thread_data) * NUM);
for (i = 0; i < NUM; i++) {
thread_data[i].thread_num = i;
pthread_create (&thread_data[i].thread, NULL, thread_func, &thread_data[i]);
}
/* And wait for them to finish... */
for (i = 0; i < NUM; i++) {
pthread_join (thread_data[i].thread, NULL);
}
return 0;
}
编辑:应该澄清 Apple,因为 OSX 10.5 (Leopard) 提供亲和性,如 https://developer.apple.com/library/mac/releasenotes/Performance/RN-AffinityAPI/
关于c - 如何通过 sched_setaffinity 在多个 CPU 上设置亲和性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37523936/
我想了解 linux 系统调用 sched_setaffinity() 的工作原理。这是我的问题的后续问题 here . 我有this guide ,它解释了如何使用系统调用并有一个非常简洁(有效!)
有没有一种方法可以在使用截止时间调度的同时将 cpu 亲和性设置为 linux 中的进程?我正在运行 4.16 内核。下面是我的测试代码: #define _GNU_SOURCE #include "
我目前正在使用 sched_setaffinity将线程固定到特定的 CPU 内核。 void setCpuAffinity(int id) {
我正在编写一个需要在单核上运行的程序。为了将它绑定(bind)到单核,我使用了 sched_setaffinity(),但编译器给出了警告: implicit declaration of funct
我正在尝试编写一个使用 sched_setaffinity() 的内核模块.它在 linux/sched.h 中声明但在 core.c 中实现(afaik),现在的问题是我的系统似乎没有 core.c
我到处寻找,但似乎无法完成。我试图避免的是: “通过 fork(2) 创建的子级继承其父级的 CPU 亲和性掩码。” 来源:https://manpages.debian.org/testing/ma
我有两 block 配备不同 ARM CPU 的主板,一 block 2x 内核 - 运行 Linux 内核 4.1.x,另一 block 4x 内核 - 运行 3.10。在那些 Linux 安装中,
我正在使用带有 Alpha ISA 的完整系统模拟器 (GEM5)。我已成功交叉编译(使用 gcc-4.3.2、glibc-2.6.1)Linux 2.6.27 for Alpha。现在,我正在交叉编
很多关于 sched_setaffinity 的帖子,但几乎没有关于在内核空间中使用它的帖子。 我使用的是 4.14.79 内核。 我尝试使用调用 sched_setaffinity 的用户空间方法,
谁能告诉我如果我跑会发生什么 taskset -c 7 ./fred.x 但是在 fred.x 中,一个线程正在调用 sched_setaffinity 来绑定(bind)到核心 6? 该线程是否会获
我正在编写一个 linux 内核模块,该模块需要将两个线程固定在两个不同的 cpu 上。我计划在将 sched_setaffinity() 导出到内核后使用它。是否还有其他相同的导出功能? 另外,如果
我在 nginx source 中看到这样的代码: if (sched_setaffinity(0, 32, (cpu_set_t *) &cpu_affinity) == -1) {
我将/proc/sys/kernel/core_pattern 设置为将核心转储管道传输到我的程序。该程序调用一个shell脚本(使用“系统”),该脚本又调用我的测试程序,附加。此测试程序尝试为任何
我调用内核函数 sched_setaffinity() 以尝试使用 CPU 锁定内核线程,但它总是失败,错误号 22 显示“参数无效”。该机器运行 Fedora 15,内核版本为 2.6.38。 如果
我想通过 sched_affinity 在多个 CPU 上设置亲和性,如下所示。 void pin(pid_t t, int cpu) { cpu_set_t cpuset; CPU_ZERO
只有一个kthread,我想控制它在特定的CPU上运行。主进程通过kthread_create()和wake_up_process()函数创建并唤醒kthread。创建 kthread 时,maie
对于我可以用来为系统上的 sched_setaffinity 调用创建 CPU_SET 的 CPU 数量的正确值是多少,我有些困惑。 我的/proc/cpuinfo 文件: processor :
是否可以在使用 Android NDK 编译的原生 C 代码中设置 CPU 亲和性?由于系统使用的是 Linux 内核,应该可以使用 sched_setaffinity/sched_getaffini
我在一台有 1 个插槽、4 个内核的服务器上用 Linux 做了一个 sched_setaffinity 测试,以下/proc/cpuinfo 显示 cpu 信息: processor :
我已经编写了一段代码,除了父进程之外还有 7 个进程,所以总和是 8 ...我设法使每个进程绑定(bind)到不同的线程..即我有 intel core-i7 ..它有4 个核心 X 2 个线程/核心
我是一名优秀的程序员,十分优秀!