You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++使用getrusage测内存时如何重置ru_maxrss峰值统计

算法内存基准测试问题记录与实现方案

背景

在个人数值物理项目开发中,需要对比同一问题下不同算法实现的内存占用表现。前期调研得知,引入<sys/resource.h>头文件后可调用getrusage()接口,通过返回结构体的ru_maxrss字段获取进程最大内存使用量,该接口的已知使用限制不会影响本次测试需求。
初始基准测试逻辑为遍历不同的参数N取值,分别统计各算法的运行耗时与内存占用,代码结构如下:

int minN = 6;
int maxN = 16;
std::chrono::steady_clock::time_point start;
std::chrono::steady_clock::time_point finish;

std::cout << "Naive:" << std::endl;
for (int N = minN; N <= maxN; N+=2) {
    struct rusage usage{};
    start = std::chrono::steady_clock::now(); 
    //do work...
    finish = std::chrono::steady_clock::now();
    int ret = getrusage(RUSAGE_SELF, &usage);

    long time_ns = std::chrono::duration_cast<std::chrono::nanoseconds>(finish - start).count();
    long max_ram_byte = usage.ru_maxrss;
    std::cout << "N = " << N << ", time = " << time_ns/1e9 << " s, ram = " << max_ram_byte << " KB" << std::endl;
}

测试遇到的问题

测试时发现核心缺陷:ru_maxrss统计的是进程从启动到调用时刻全生命周期的峰值内存占用,大内存对象离开作用域释放内存后,该统计值不会回落。一旦程序运行到内存占用较高的测试用例、触达全局内存峰值后,后续所有测试用例读取到的ru_maxrss都会固定为该历史峰值,内存统计结果完全失效。
典型失效测试输出如下:

Naive:
N = 6, time = 0.022541 s, ram = 8028 KB
N = 8, time = 0.0234674 s, ram = 65360 KB
N = 10, time = 0.373676 s, ram = 135284 KB
N = 12, time = 21.7536 s, ram = 631792 KB
Magnetization:
N = 6, time = 0.000166585 s, ram = 631792 KB
N = 8, time = 0.00158378 s, ram = 631792 KB
N = 10, time = 0.022255 s, ram = 631792 KB
N = 12, time = 0.405172 s, ram = 631792 KB
Momentum:
N = 6, time = 0.000175482 s, ram = 631792 KB
N = 8, time = 0.000766058 s, ram = 631792 KB
N = 10, time = 0.00658272 s, ram = 631792 KB
N = 12, time = 0.0728279 s, ram = 631792 KB
Parity:
N = 8, time = 0.000986243 s, ram = 631792 KB
N = 12, time = 0.0528302 s, ram = 631792 KB
Spin Inversion:
N = 8, time = 0.00111167 s, ram = 631792 KB
N = 12, time = 0.050363 s, ram = 631792 KB

初始疑问

明确该特性是getrusage()的设计逻辑后,提出三个问题:

  • 是否存在方法可以重置ru_maxrss的峰值统计值?
  • 若无法重置,是否有无需依赖专用基准测试库、可在程序内部直接调用的简易内存占用测量方案?
  • ru_maxrss字段的返回值单位是字节(B)还是千字节(KB)?在N=8测试场景中,存储了包含65536个double类型元素的矩阵作为内存占用主体,预期占用约65536字节;按照接口文档说明返回值单位为KB,但测试得到的65360数值与预期字节数意外接近,需要确认该字段的单位规则,以及数值接近是否仅为巧合。

最终实现方案

目前已通过解析/proc/self/stat文件实现了符合需求的内存测量,可供后续开发者参考:

注意:stat文件的第24项rss字段单位为内存页,将其值乘以4096即可得到近似的内存占用字节数
实现代码如下:

std::cout << "Naive:" << std::endl;
for (int N = minN; N <= maxN; N+=2) {
    start = std::chrono::steady_clock::now();
    // do work...
    finish = std::chrono::steady_clock::now();
    std::ifstream statFile("/proc/self/stat");
    std::string statLine;
    std::getline(statFile, statLine);
    std::istringstream iss(statLine);
    std::string entry;
    long long memUsage;
    for (int i = 1; i <= 24; i++) {
        std::getline(iss, entry, ' ');
        if (i == 24) {
            memUsage = stoi(entry);
        }
    }

    long time_ns = std::chrono::duration_cast<std::chrono::nanoseconds>(finish - start).count();
    std::cout << "N = " << N << ", time = " << time_ns/1e9 << " s, ram = " << 4096*memUsage/1e9 << " GB" << std::endl;
}

内容的提问来源于stack exchange,提问作者Max Maschke

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 22:30:57