通过同时运行两个可执行文件来测量内存使用情况

Posted

技术标签:

【中文标题】通过同时运行两个可执行文件来测量内存使用情况【英文标题】:Measure memory usage by running two executables at the same time 【发布时间】:2015-03-25 14:38:35 【问题描述】:

我编译了一个代码并运行了两个可执行文件:exec1exec 2。 他们都有相同的代码,但他们有不同的输入。 我作为操作系统使用Kubuntu(非常新手)。

每个可执行文件都通过使用 sqlite 库与两个数据库进行交互:一个数据库用于exec1,另一个用于exec2 每个可执行文件都需要加载和解析一个 xml 文件

CPU 信息

processor       : 5
vendor_id       : GenuineIntel
cpu family      : 6
model           : 44
model name      : Intel(R) Xeon(R) CPU           X5650  @ 2.67GHz
stepping        : 2
microcode       : 0x10
cpu MHz         : 2660.022
cache size      : 12288 KB
physical id     : 0
siblings        : 6
core id         : 10
cpu cores       : 6
apicid          : 20
initial apicid  : 20
fpu             : yes
fpu_exception   : yes
cpuid level     : 11
wp              : yes

问题

是否有可能知道同时运行两个可执行文件是否会影响两个可执行文件的速度? 如何测量每个可执行文件使用的内存量? 是否可以直观地完成?

使用脚本

使用以下脚本(需要更新):

echo "timestamp,VmSize,VmRSS";
while awk ' printf "%s,%s,%s\n", systime(), $1, $2' /proc/13417/statm; do sleep 1; done 


timestamp,VmSize,VmRSS
1427295959,92907,49655
1427295960,92907,49655
1427295961,92907,49655
1427295962,92907,49655
1427295964,92907,49655
1427295965,92907,49655

【问题讨论】:

对于时间比较:与一个接一个地运行相比?我很确定运行 两个 不会比运行 一个 快。 是的@ScottHunter 比较了一个接一个地跑 【参考方案1】:

是否可以知道同时运行两个可执行文件是否会影响两个可执行文件的速度?

如果运行一个可执行文件需要 N 秒,而运行其中两个可执行文件需要相同的 N 秒(没有时间差),那么它们不会相互影响。

如何测量每个可执行文件使用的内存量?

您可以使用这个小脚本每秒以 csv 格式输出时间戳和内存使用情况。

echo "timestamp,VmSizeKB,VmRssKB";
while awk ' printf "%s,%s,%s\n", systime(), $1 * 4, $2 * 4' /proc/<pid>/statm; do sleep 1; done

&lt;pid&gt; 替换为您的进程 ID。

是否可以直观地做到这一点?

然后将该 csv 导入谷歌文档或其他电子表格应用程序并构建一个漂亮的图表。您只对 VmRSS 列感兴趣,这是您的进程使用的物理内存量。

【讨论】:

真的很有趣,我现在正在运行它。它比 top 简单得多。 我会发布结果。 @HaniGoc 您使用的是初始版本。新版本将数字乘以 4096 得到以字节为单位的测量值。 我会更新它。 @Maxim 你能检查我剩下的问题吗?我检查了我的电脑的总物理内存是多少,对吗?【参考方案2】:

假设您有(至少)两个物理 CPU 内核可用并且您的程序没有庞大的私有工作集,并行运行两个实例通常比一个接一个运行它们要快。在某些情况下,情况正好相反,但通常情况下,在健康的情况下,情况就会如此。

任何两个实例(并发或一个接一个)在正常情况下将使用缓冲区缓存中相同的映射页面来存储可执行和只读数据,但同时运行的进程更有可能拥有最后一级缓存中的内存,它们同时在不同的 CPU 内核上运行指令。 此外,使用fork(见下文)创建的两个实例只会运行一次 CRT 初始化和 fork 之前的任何初始化代码,并且不需要额外的 shell。

(当然,如果您的进程执行大量锁定或大量并发无缓冲 I/O,或者如果它们消耗大量内存,那么这些优势将变得完全微不足道,并变成劣势,因此它们开始干扰不健康方式。因此,“通常”,而不是总是。)

运行同一程序两次(实际上是三次,如果您计算父项)和测量(并比较它是否比一次调用更快)的最简单方法是调用 fork 两次并自己进行测量。实际上调用fork 一次 就足以运行这两个实例,但是执行您想要做的测量就有点麻烦了。

在你fork 两次之后,你有两个子进程正在运行(然后它们可以做他们应该做的任何事情)。父进程使用clock_gettime 获取当前时间并阻塞waitpid(两次)。

waitpid 之后,父级再次调用clock_gettime 并调用times

您现在有空:

开始时间 结束时间(您可以从中减去开始时间) 孩子的用户和内核时间

这样,您可以准确地知道执行子(子)需要多长时间,以及他们在执行此操作时消耗了多少 CPU 时间(用户和内核)。

【讨论】:

我认为我的问题并不完整。 @Damon 关注您对并发无缓冲 I/O 的评论。 1. 我正在运行的程序通过使用 sqlite 库与两个数据库进行交互:一个用于 exec1 的数据库,另一个用于 exec。 2.还需要加载和解析一个xml文件。这些是否被视为无缓冲 I/O? 好吧,正常的 I/O 是缓冲的,由于预读,您读取的大多数数据在很久以前就被提取了。您写入的数据进入“脏”的缓冲区页面,并被懒惰地写回。到目前为止,当两个进程使用磁盘时,您通常不会看到太大的影响——相反,它们可能想要读取相同的页面。但是,当与数据库(同一个数据库)通信或进行一般的无缓冲写入时,您很快就会开始感觉到磁盘是一个物理实体,它只能这样做,每秒有这么多的请求。 这取决于您配置的一致性级别,但通常您的数据库(sqlite 或其他)需要写入日志(不一定是无缓冲的,但经常),并且必须锁定任一行或完整的表,或基础数据库文件(取决于实现)以应用更改。就目前而言,是的,两个竞争的过程很可能会产生不利影响。【参考方案3】:

你可以跑

myprogram argone &
myprogram argtwo &

在后台运行两个运行相同程序的进程。

您可能还对batchnohuptop 感兴趣

【讨论】:

你能帮忙分析一下吗@Basile Starynkevitch。

以上是关于通过同时运行两个可执行文件来测量内存使用情况的主要内容,如果未能解决你的问题,请参考以下文章

IPC 通过两个不同的可执行文件?

Mac 命令行中添加命令直接调用可执行文件

如何比较内联函数和普通函数的内存使用情况?

一个可执行文件的生成过程到进程在内存中的分布

我有两个exe文件,怎样用一个东西让他们同时启动

可执行程序加载到内存的过程