Measuring clock cycles of another PID

151 Views Asked by At

I am looking to measure total clock cycles used by a program. I am hoping to measure this from another process.

  • clock_t can be used to measure a block of code but doesn't work for me because I want to measure total clock cycles of another program

  • /proc/PID/stat can tell you the total user time and kernel time a process has used but I am hoping to capture this information when the process completes

Any other ideas for how to reliably capture this?

1

There are 1 best solutions below

0
Erick Arce On

Yes, albeit I am not sure how reliable it is. c has some built in libraries you can use for this. I chose to do it in Rust but you can probably look up the parts you need. TLDR spawning a child process and rusage

extern crate nix;

use std::process::Command;
use std::process::Output;
use libc::{c_long, rusage, suseconds_t, timeval, time_t, getrusage, RUSAGE_CHILDREN};

pub fn execute_cmd(bash_cmd: String) -> (u64, Output) {
    let mut usage = rusage {
        ru_utime: timeval{ tv_sec: 0 as time_t, tv_usec: 0 as suseconds_t, },
        ru_stime: timeval{ tv_sec: 0 as time_t, tv_usec: 0 as suseconds_t, },
        ru_maxrss: 0 as c_long,
        ru_ixrss: 0 as c_long,
        ru_idrss: 0 as c_long,
        ru_isrss: 0 as c_long,
        ru_minflt: 0 as c_long,
        ru_majflt: 0 as c_long,
        ru_nswap: 0 as c_long,
        ru_inblock: 0 as c_long,
        ru_oublock: 0 as c_long,
        ru_msgsnd: 0 as c_long,
        ru_msgrcv: 0 as c_long,
        ru_nsignals: 0 as c_long,
        ru_nvcsw: 0 as c_long,
        ru_nivcsw: 0 as c_long,
    };

    let _result = nix::sys::wait::waitpid(None, None);

    let output = Command::new(bash_cmd.clone())
        .output()
        .expect("Failed to execute cmd");

    unsafe { getrusage( RUSAGE_CHILDREN, (&mut usage) as *mut rusage); }

    let user_secs = usage.ru_utime.tv_sec as u64;
    let user_usecs = usage.ru_utime.tv_usec as u64;

    let sys_secs = usage.ru_stime.tv_sec as u64;
    let sys_usecs = usage.ru_stime.tv_usec as u64;

    let user_time = (user_secs * 1_000_000) + user_usecs;
    let sys_time = (sys_secs * 1_000_000) + sys_usecs;

    return (user_time + sys_time, output);
}