CPUSETS(处理器组)
-------
内容:
=========
1. Cpusets
1.1 什么是cpusets?
1.2 为什么需要cpusets?
1.3 cpusets如何实现?
1.4 什么是专用cpusets?
1.5 什么是memory_pressure?
1.6 什么是内存扩散?
1.7 什么是sched_load_balance?
1.8 什么是sched_relax_domain_level?
1.9 如何使用cpusets?
2.使用示例和语法
2.1 基本用法
2.2 添加/删除cpus
2.3 设置标志
2.4 附加流程
3.问题
4.联系方式
1. Cpusets
==========
1.1什么是cpusets?
----------------------
Cpuset提供了一种将一组CPU和内存节点分配给一组任务的机制。 在本文档中,“内存节点”是指包含内存的在线节点。
处理器组将任务的CPU和内存位置限制为仅任务当前CPU集内的资源。 它们形成了在虚拟文件系统中可见的嵌套层次结构。 除了已经存在的功能以外,这些是管理大型系统上动态作业放置所需的基本功能。
cpuset使用Documentation/cgroup-v1/cgroups.txt中描述的通用cgroup子系统。
通过使用 sched_setaffinity(2) 系统调用将CPU包括在其CPU亲和力掩码中,以及使用 mbind(2) 和 set_mempolicy(2) 系统调用将内存节点包括在其内存策略中,均通过该任务的cpuset进行过滤,过滤掉不在该cpuset中的所有CPU或内存节点。 调度程序不会在其 cpus_allowed 向量中不允许的CPU上调度任务,并且内核page分配器不会在请求任务的 mems_allowed 向量中不允许的节点上分配页面。
用户级代码可以按名称在cgroup虚拟文件系统中创建和销毁cpuset,管理这些cpuset的属性和权限,以及为每个cpuset分配了哪些CPU和内存节点,指定并查询任务分配给哪个cpuset,并列出 分配给cpuset的任务pid。
通常,仅通过让操作系统自动在请求的任务之间共享可用的CPU和内存资源,便可以以足够的效率来运行大小较小的系统。
但是大型系统可以通过将作业明确放置在适当大小的系统子集上而受益,大型系统得益于精心的处理器和内存放置以减少内存访问时间和竞争,并且通常代表客户较大的投资。
这在以下方面尤其有价值:
*运行同一Web应用程序的多个实例的Web服务器,
*运行不同应用程序的服务器(例如,Web服务器和数据库),或
*运行具有高性能要求的大型HPC应用程序的NUMA系统。
这些子集或“软分区”必须能够随着作业组合的变化而动态调整,而不会影响其他同时执行的作业。 当更改内存位置时,也可以移动正在运行的作业页面的位置。
内核cpuset补丁提供了有效实现此类子集所需的最低限度的基本的内核机制。 它利用Linux内核中现有的CPU和内存放置功能,以避免对关键调度程序或内存分配器代码产生任何其他影响。
1.3 cpusets如何实现?
---------------------------------
Cpuset提供了Linux内核机制来约束一个或一组进程使用哪个或哪些CPU和内存节点。
Linux内核已经有一对机制来指定可以在哪个CPU上调度任务(sched_setaffinity),以及可以在哪个Memory Node上获得内存(mbind,set_mempolicy)。
Cpusets扩展了以下两种机制:
- Cpuset是内核已知的一组允许的CPU和内存节点。 - 系统中的每个任务都通过任务结构体中指向引用计数的cgroup结构的指针连接到cpuset。 - 对sched_setaffinity的调用仅过滤到该任务的cpuset中允许的CPU。 - 对mbind和set_mempolicy的调用仅过滤到该任务的cpuset中允许的那些内存节点。 - 根cpuset包含所有系统CPU和内存节点。 - 对于任何cpuset,可以定义包含父CPU和内存节点资源的子集的子cpuset。 - 可以将cpuset的层次结构mount在/dev/cpuset上,以便从用户空间进行浏览和操作。 - 一个cpuset可能被标记为“独占”,以确保没有其他cpuset(直接祖先和后代除外)可以重叠包含任何CPU或内存节点。 - 您可以列出附加到任何cpuset的所有任务(按pid)。
cpusets的实现需要一些简单的钩子连接到内核的其余部分,而在性能关键路径中则没有:
-在init/main.c中,在系统启动时初始化根cpuset。 -在fork和exit中,将任务附加到cpuset或分离。 -在 sched_setaffinity 中,通过该任务的cpuset中所允许的内容屏蔽请求的CPU。 -在sched.c migrate_live_tasks()中,如果可能的话,将迁移任务保持在其cpuset允许的CPU内。 -在mbind和set_mempolicy系统调用中,通过该任务的cpuset中允许的内容屏蔽请求的内存节点。 -在page_alloc.c中,将内存限制为允许的节点。 -在vmscan.c中,将页面恢复限制为当前cpuset。
您应该挂载“cgroup”类型文件系统,以便浏览和修改内核当前已知的cpuset。 没有为cpuset添加新的系统调用-通过此cpuset文件系统提供对查询和修改cpuset的所有支持。
每个任务的 /proc/<pid>/status 文件增加了四行,分别以以下两种格式显示任务的 cpus_allowed(它可以在哪些CPU上调度)和 mems_allowed(它可以在哪些内存节点上分配内存)。 下面的例子:
Cpus_allowed: ffffffff,ffffffff,ffffffff,ffffffff Cpus_allowed_list: 0-127 Mems_allowed: ffffffff,ffffffff Mems_allowed_list: 0-63
每个cpuset由cgroup文件系统中的目录表示,该目录包含(在标准cgroup文件之上)描述该cpuset的以下文件:
-cpuset.cpus:该cpuset中的CPU列表 -cpuset.mems:该cpuset中的内存节点列表 -cpuset.memory_migrate 标志:如果设置,则将内存页移至cpusets节点 -cpuset.cpu_exclusive 标志:cpu放置是否独占? -cpuset.mem_exclusive 标志:内存放置是否独占? -cpuset.mem_hardwall 标志:内存分配是否为硬壁 -cpuset.memory_pressure:测量cpuset中有多少分页压力 -cpuset.memory_spread_page 标志:如果设置,则在允许的节点上平均分布页面缓存 -cpuset.memory_spread_slab 标志:如果设置,则在允许的节点上平均分布slab缓存 -cpuset.sched_load_balance 标志:如果设置,则在该cpuset上的CPU内进行负载平衡 -cpuset.sched_relax_domain_level:迁移任务时的搜索范围
此外,只有根cpuset才具有以下文件:
-cpuset.memory_pressure_enabled 标志:计算memory_pressure?
使用mkdir系统调用或shell命令创建新的cpuset。 如上所述,通过写入该cpusets目录中的相应文件,可以修改cpuset的属性,例如其标志,允许的CPU和内存节点以及附加的任务。
嵌套cpuset的命名层次结构允许将大型系统划分为嵌套的,可动态更改的“软分区”。
将每个任务的任何子代在派生时自动继承的每个任务附加到cpuset,可以将系统上的工作负载组织到相关的任务集中,从而使每个任务集都只能使用特定cpuset的CPU和内存节点 。 如果必要的cpuset文件系统目录的权限允许,则任务可以重新附加到任何其他cpuset。
使用sched_setaffinity,mbind和set_mempolicy系统调用,使这种“大型”系统的管理与在单个任务和内存区域上完成的详细放置顺利集成。
以下规则适用于每个cpuset:
- 其CPU和内存节点必须是其父级的子集。 - 除非其父级将其标记为独占,否则子级不能将其标记为独占。 - 如果其cpu或内存是互斥的,则它们不得与任何同级重叠。
这些规则以及cpuset的自然层次结构可以有效执行排他保证,而不必每次更改任何cpuset时都扫描所有cpuset,以确保没有任何重叠cpuset。 另外,使用Linux虚拟文件系统(vfs),以最少的附加内核代码量,表示了cpuset层次结构可为cpuset提供熟悉的权限和名称空间,
根(top_cpuset)cpuset中的cpus和mems文件是只读的。 cpus文件使用CPU热插拔通知程序自动跟踪 cpu_online_mask 的值,而mems文件使用 cpuset_track_online_nodes()挂钩自动跟踪 node_states[N_MEMORY](即具有内存的节点)的值。
1.4 什么是独占cpusets?
--------------------------------
如果cpuset是cpu或mem独占的,则除直接祖先或后代之外,其他任何cpuset均不得共享任何与其相同的CPU或内存节点。
cpuset.mem_exclusive *或* cpuset.mem_hardwall 的 cpuset 是“硬壁的”,即,它限制了内核在多个用户之间通常共享的页面,缓冲区和其他数据的内核分配。
所有cpuset,无论是否为硬墙,都限制为用户空间分配内存。 这样可以配置系统,以便几个独立的作业可以共享公用内核数据,例如文件系统页面,同时将每个作业的用户分配隔离在其自己的cpuset中。 为此,请构造一个大型的 mem_exclusive cpuset以容纳所有作业,并为每个单独的作业构造子级 non-mem_exclusive cpuset。 即使是 mem_exclusive cpuset,也只允许将少量的典型内核内存(例如来自中断处理程序的请求)带到外部。
1.5 什么是 memory_pressure?
-----------------------------
cpuset的memory_pressure提供了每个cpuset的简单度量,用于度量cpuset中的任务试图释放cpuset节点上的使用中的内存以满足其他内存请求的速率。
这使批处理管理器可以监视在专用cpuset中运行的作业,以有效地检测该作业造成的内存压力级别。
这在运行大量提交作业的紧密管理的系统上很有用,
它们可以选择终止或重新分配那些试图使用比分配给它们的节点更多的内存的优先级的作业,
以及紧密耦合,长期运行的作业, 大规模并行科学计算作业,
如果开始使用超出允许范围的内存,将大大无法达到所需的性能目标。
此机制为批处理管理器提供了一种非常经济的方式来监视cpuset的内存压力迹象。
由批次管理器或其他用户代码决定如何处理并采取措施。
==>除非通过在特殊文件 /dev/cpuset/memory_pressure_enabled 中写入“ 1”来启用此功能,############
否则 __alloc_pages() 的重新平衡代码中针对该度量的钩子将简化为仅注意到 cpuset_memory_pressure_enabled 标志为零。
因此,只有启用了此功能的系统才能计算指标。
为什么要按每cpuset运行平均值:
由于此仪表是按CPU而不是按任务或mm的,因此在大型系统上,监视此指标的批处理调度程序所施加的系统负载将大大减少,
因为可以避免在每组查询上都扫描任务列表。
因为此仪表是运行平均值,而不是累加计数器,所以批处理调度程序可以通过一次读取来检测内存压力,
而不必在一段时间内读取和累加结果。
由于此仪表是per-cpuset而不是per-task或per-mm的,因此批处理调度程序可以通过一次读取就可以获取关键信息,CPU的内存压力。
必须查询和累积cpuset中所有(动态变化的)任务集的结果。。
如果每个cpuset简单数字滤波器(输入同步(直接)页面回收代码),
则该数字滤波器会保留(需要一个自旋锁和每个cpuset 3个数据字),并由附加到该cpuset的任何任务更新。
每个cpuset文件提供一个整数,表示由cpuset中的任务导致的直接页面回收的近期的速率(半衰期为10秒),
以每秒尝试回收的次数乘以1000为单位。
Cgroup内核文档翻译(67)——Documentation/cgroup-v1/cpusets.txt
原文:https://www.cnblogs.com/hellokitty2/p/14288835.html