为什么“change_protection”在将大量数据加载到 RAM 时会占用 CPU?

2024-03-24

我们建立了一个内存数据库,单个数据库占用约 100-150G RAMVec https://doc.rust-lang.org/std/vec/struct.Vec.html,其填充如下:

let mut result = Vec::with_capacity(a_very_large_number);
while let Ok(n) = reader.read(&mut buffer) {
    result.push(...);
}

perf top表明时间大部分花在这个“change_protection”函数上:

Samples: 48K of event 'cpu-clock', Event count (approx.): 694742858
 62.45%  [kernel]              [k] change_protection
 18.18%  iron                  [.] database::Database::init::h63748
  7.45%  [kernel]              [k] vm_normal_page
  4.88%  libc-2.17.so          [.] __memcpy_ssse3_back
  0.92%  [kernel]              [k] copy_user_enhanced_fast_string
  0.52%  iron                  [.] memcpy@plt

随着越来越多的数据加载到 RAM 中,该函数的 CPU 使用率也会增加:

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
12383 iron      20   0  137g  91g 1372 D 76.1 37.9  27:37.00 iron

该代码正在 r3.8xlarge AWS EC2 实例上运行,并且透明大页已被禁用。

[~]$ cat /sys/kernel/mm/transparent_hugepage/defrag
always madvise [never]
[~]$ cat /sys/kernel/mm/transparent_hugepage/enabled
always madvise [never]

cpuinfo

processor   : 0
vendor_id   : GenuineIntel
cpu family  : 6
model       : 62
model name  : Intel(R) Xeon(R) CPU E5-2670 v2 @ 2.50GHz
stepping    : 4
microcode   : 0x428
cpu MHz     : 2500.070
cache size  : 25600 KB
physical id : 0
siblings    : 16
core id     : 0
cpu cores   : 8
apicid      : 0
initial apicid  : 0
fpu     : yes
fpu_exception   : yes
cpuid level : 13
wp      : yes
flags       : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx rdtscp lm constant_tsc rep_good nopl xtopology eagerfpu pni pclmulqdq ssse3 cx16 pcid sse4_1 sse4_2 x2apic popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm xsaveopt fsgsbase smep erms
bogomips    : 5000.14
clflush size    : 64
cache_alignment : 64
address sizes   : 46 bits physical, 48 bits virtual
power management:

kernel

3.14.35-28.38.amzn1.x86_64

真正的问题是为什么该函数有这么多开销?


这似乎是操作系统问题,而不是特定 Rust 函数的问题。

大多数操作系统(包括 Linux)都使用请求寻呼 https://en.wikipedia.org/wiki/Demand_paging。默认情况下,Linux不会为新分配的内存分配物理页。相反,它将为所有已分配的内存分配具有只读权限的单个零页(即,所有虚拟内存页将指向该单个物理内存页)。

如果您尝试写入内存,则会发生页面错误,将分配新页面,并相应地设置其权限。

我猜您在程序中看到了这种效果。如果你尝试第二次做同样的事情,它应该会快得多。还有一些方法可以通过以下方式控制此策略sysctl: https://www.kernel.org/doc/Documentation/vm/overcommit-accounting https://www.kernel.org/doc/Documentation/vm/overcommit-accounting.

不确定为什么禁用 THP,但在这种情况下,大页面可能会对您有所帮助,因为保护更改将针对每个大页面 (2Mib) 发生一次,而不是每个普通页面 (4KiB) 发生一次。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么“change_protection”在将大量数据加载到 RAM 时会占用 CPU? 的相关文章

  • Discord.net 无法在 Linux 上运行

    我正在尝试让在 Linux VPS 上运行的 Discord net 中编码的不和谐机器人 我通过单声道运行 但我不断收到此错误 Unhandled Exception System Exception Connection lost at
  • 如何使用可变参数宏调用嵌套构造函数?

    我正在尝试在 Rust 中创建一个宏 让我可以编写 make list 1 2 3 代替 Node new 1 Node new 2 Node new 3 None 它应该适用于任意数量的 参数 包括零 这是我到目前为止所拥有的 macro
  • PHP 从命令行启动 gui 程序,但 apache 不启动

    首先 我阅读了有类似问题的人的一些帖子 但所有答案都没有超出导出 DISPLAY 0 0 和 xauth cookies 这是我的问题 提前感谢您的宝贵时间 我开发了一个小库 它使用 OpenGL 和 GLSL 渲染货架 过去几天我将它包装
  • Linux 可执行文件与 OS X“兼容”吗?

    如果您在基于 Linux 的平台上用 C 语言编译一个程序 然后将其移植以使用 MacOS 库 它会工作吗 来自编译器的核心机器代码在 Mac 和 Linux 上兼容吗 我问这个问题的原因是因为两者都是 基于 UNIX 的 所以我认为这是真
  • 在 Linux 上使用多处理时,TKinter 窗口不会出现

    我想生成另一个进程来异步显示错误消息 同时应用程序的其余部分继续 我正在使用multiprocessingPython 2 6 中的模块来创建进程 我试图用以下命令显示窗口TKinter 这段代码在Windows上运行良好 但在Linux上
  • 为什么`Option`支持`IntoIterator`?

    我试图迭代字符串向量的一个子部分 即Vec
  • C语言中如何通过内存地址映射函数名和行号?

    如何用 GCC 中的内存地址映射回函数名称和行号 即假设一个 C 语言原型 void func Get the address of caller maybe this could be avoided MemoryAddress get
  • 为arm构建WebRTC

    我想为我的带有arm926ej s处理器的小机器构建webrtc 安装 depot tools 后 我执行了以下步骤 gclient config http webrtc googlecode com svn trunk gclient s
  • 多处理:仅使用物理核心?

    我有一个函数foo它消耗大量内存 我想并行运行多个实例 假设我有一个有 4 个物理核心的 CPU 每个核心有两个逻辑核心 我的系统有足够的内存来容纳 4 个实例foo并行但不是 8 个 此外 由于这 8 个核心中的 4 个是逻辑核心 我也不
  • Poetry install --no-dev 需要安装 Rust 吗?

    我正在 Raspberry pi 3b Lite buster 2020 年 2 月 的容器中安装 Poetry 我使用图像arm32v7 python 3 7 slim buster 这里是Dockerfile FROM arm32v7
  • 查找哪个程序运行另一个程序

    我有一个 NAS 运行在 Redhat Linux 的有限版本上 我按照指示破解了它 这样我就可以访问 shell 这很有帮助 我还做了一些修改 其他人也做过修改 除了一个问题之外 它们似乎都工作得很好 不知何故 每隔 22 天 系统就会关
  • 在脚本内使用不带密码的 sudo

    由于某种原因 我需要作为用户在没有 sudo 的情况下运行脚本 script sh 该脚本需要 root 权限才能工作 我认为将 sudo 放入 script sh 中是唯一的解决方案 让我们举个例子 script sh bin sh su
  • 如何更改 Apache 服务器的根目录? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 如何更改 Apache 服务器的文档根目录 我基本上想要localhost从 来 users spencer projects目录而不是
  • 是否可以创建一个脚本来保存和恢复权限?

    我正在使用 Linux 系统 需要对一组嵌套文件和目录进行一些权限实验 我想知道是否没有某种方法可以保存文件和目录的权限 而不保存文件本身 换句话说 我想保存权限 编辑一些文件 调整一些权限 然后将权限恢复到目录结构中 将更改的文件保留在适
  • 我不明白 execlp() 在 Linux 中如何工作

    过去两天我一直在试图理解execlp 系统调用 但我还在这里 让我直奔主题 The man pageexeclp 将系统调用声明为int execlp const char file const char arg 与描述 execl exe
  • Linux - 从第二个选项卡获取文本

    假设我们有这样的文件 一些文本11 一些文本12 一些文本13 一些文本21 一些文本22 一些文本23 文本由制表符分隔 我们知道第 1 列中的一些文本 但希望从第 2 列中获取文本 我知道我可以通过以下方式获取线路 grep somet
  • waitpid() 的作用是什么?

    有什么用waitpid 它通常用于等待特定进程完成 或者如果您使用特殊标志则更改状态 基于其进程 ID 也称为pid 它还可用于等待一组子进程中的任何一个 无论是来自特定进程组的子进程还是当前进程的任何子进程 See here http l
  • 我如何知道 C 程序的可执行文件是在前台还是后台运行?

    在我的 C 程序中 我想知道我的可执行文件是否像这样在前台运行 a out 或者像这样 a out 如果你是前台工作 getpgrp tcgetpgrp STDOUT FILENO or STDIN FILENO or STDERR FIL
  • 子目录中的头文件(例如 gtk/gtk.h 与 gtk-2.0/gtk/gtk.h)

    我正在尝试使用 GTK 构建一个 hello world 其中包括以下行 include
  • 如何在c linux中收听特定接口上的广播?

    我目前可以通过执行以下操作来收听我编写的简单广播服务器 仅广播 hello int fd socket PF INET SOCK DGRAM 0 struct sockaddr in addr memset addr 0 sizeof ad

随机推荐

  • Java:从字符串中删除数值

    在该社区的帮助下 我成功地从用户输入中删除了数字值 但是 下面的代码将仅检索已删除的数字之前的字母字符 import java util Scanner public class Assignment2 A public static vo
  • Android:更改默认家庭应用程序

    对于某些特定要求 我需要更改 Android 默认主页应用程序 使用我的自定义主页应用程序 我的应用程序内的一个设置 将切换默认主页 我的应用程序或以前的主页 我不希望用户进行非常复杂的 Android 设置 任何人都可以帮我解决一下它在哪
  • 在哪里可以初始化模块范围的变量?

    我正在尝试做这样的事情 angular module MyModule ui config function rootScope rootScope Gender M Male F Female U Unknown 但我收到这个错误 未捕获
  • Bash 中的 [ 和 [[ 有什么区别? [复制]

    这个问题在这里已经有答案了 我查看了 bash 手册页和 说它使用条件表达式 然后我查看了条件表达式部分 它列出了与test and 所以我想知道 有什么区别 and 在巴什 bash 的改进是 命令 它具有多项增强功能 如果您编写针对 b
  • 使用 Android 格式化字符串时间戳

    出于某种原因 这让我抓狂了 我在 Android 中有一个 UNIX 时间戳作为字符串 我想要做的就是对其进行格式化 以便它返回用户的 droid 时区中的日期 时间 我可以将其转换为时间戳 但它使用 GMT 而不是其本地化区域 Thank
  • 如何一次性将排序规则更改为utf8_bin

    我已将所有数据库表的排序规则设置为latin1 swedish ci现在我意识到我应该使用utf8 bin or utf8 general ci 如何将表中的排序规则更改为utf8 bin or utf8 general ci一气呵成 我可
  • 谷歌地图自动完成、带有边界框的严格边界和自定义 UI

    我有一个输入 我想用作谷歌地图自动完成搜索 但具有一些自定义 UI 制作标准自动完成小部件 https developers google com maps documentation javascript reference Autoco
  • 如何在布线级别验证 Rails 中的静态参数?

    我目前有以下宁静的网址 questions 2011 05 我的提问路线是 match questions year month gt Questions month 如何在路线级别验证上述年份和月份参数 以便 年和月是整数 最短 最长一年
  • android numberpicker 用于浮点数

    我们应用程序的用户应该能够调整浮点数 目前 我用所有可能的值填充了 ArrayAdapter 并将其附加到微调器 这个解决方案并没有真正满足我们的期望 因为旋转下拉框太高了 有没有更好的办法 我正在查看 Numberpicker 但这似乎只
  • 造型 ActionBar Sherlock

    我正在尝试自定义我的 sherlock 操作栏 但我在 style xml 中编写的任何代码都未被识别 在我的清单文件中 android theme style Theme Sherlock 我的样式 xml
  • 通过 nginx 和 ServiceStack 在 fastcgi-mono-server 上进行小负载测试后,网关 502 错误

    我正在尝试在 nginx 和 fastcgi mono server 下使用 ServiceStack 运行 Web 服务 API 服务器启动正常 API 已启动并运行 我可以通过 ServiceStack Profiler 在浏览器中查看
  • Scala-IDE 中工作表中的类导致错误

    只需在工作表中键入以下内容即可实例化一个类 注意 工作表是使用 文件 gt 新建 gt Scala 工作表 创建的 sc文件 不是普通文件 scala文件 并单击保存会导致虚假错误 鼠标移到 这条线上有多个标记 简单表达式的非法开头 符合预
  • 基于检查约束的分区修剪未按预期工作

    为什么下面的查询计划中包含表 events 201504 根据我的查询和该表的检查约束 我希望查询规划器能够完全修剪它 database d events 201504 Table public events 201504 Column T
  • Clojure WebSocket 应用程序的 nginx 产品设置

    我正在尝试部署我的第一个 Clojure WebSocket 应用程序 我想我已经很接近了 我在本地得到了很好的响应 看起来端点想要面对外界 当我运行时我看到端口是开放的netstat 但没有任何反应 我确信我的某些设置不正确nginx 我
  • 如何在 Vue.js 方法中使用外部 JavaScript 对象

    我正在尝试让 Stripe 与我的 Vue js 2 应用程序一起工作 出于 PCI DSS 原因 Stripe 要求其 Javascript总是从加载js stripe com https stripe com docs web setu
  • 我应该使用 URLDownloadToFile 吗?

    我正在寻找用 C 下载文件的最简单方法 在 Windows 上 URLDownloadToFile 听起来很棒 并且不需要我使用curl 或其他我不需要的胖库 这个函数有什么要求 它将在哪些 Windows 上运行 Thanks http
  • 基于 JavaScript 的开源客户端 2D 数据绘图?

    我想知道是否有任何使用 JavaScript 在客户端运行的 2D 图形绘制库 基本思想是 您可以在浏览器中放置一个绘图 用户可以更改 X 和 Y 比例和限制 放大和缩小等内容 而无需不断地从服务器重新加载网页 数据本身将通过 AJAX 获
  • 尝试在空对象引用上调用虚拟方法“androidx.navigation.NavGraph androidx.navigation.NavDestination.getParent()”

    我创建了一个 Android 应用程序 并从图库中添加了 导航抽屉活动 删除并重命名了菜单项 启动应用程序后 当我单击抽屉活动中的任何菜单项时 出现以下错误 java lang NullPointerException Attempt to
  • 布局位于状态栏和软键下方

    我不确定我是如何得到这个的 而且我找不到类似的东西 但我的软件导航和状态栏是在我的布局上绘制的 而不是我的布局适合它们之间 如何让我的布局绘制在它们之间而不是下面 Edit 看来这就是罪魁祸首 位于样式中
  • 为什么“change_protection”在将大量数据加载到 RAM 时会占用 CPU?

    我们建立了一个内存数据库 单个数据库占用约 100 150G RAMVec https doc rust lang org std vec struct Vec html 其填充如下 let mut result Vec with capa