10

I am comparing a few system calls where I read/write from/to memory. Is there any API defined to measure page faults (pages in/out) in C ?

I found this library libperfstat.a but it is for AIX, I couldn't find anything for linux.

Edit: I am aware of time & perf-stat commands in linux, just exploring if there is anything available for me to use inside the C program.

osgx
  • 80,853
  • 42
  • 303
  • 470
brokenfoot
  • 9,630
  • 9
  • 46
  • 71
  • 1
    This is not a C library but you can use `time -v a.out` to display a plethora of info about your program, including page faults. – Daniel Apr 25 '14 at 20:54
  • In the 1st line of the link it says "collection of `C` programming language subroutines". I know about the `time` command, but was exploring if anything can be done from inside the `C` program. Thanks though! – brokenfoot Apr 25 '14 at 20:59
  • " available for me inside the C program." -- can you tolerate inaccuracy? There's probably not much of an API for this because it's so poorly defined (faults can happen on your way into and out of this system call, so as of when do you want it to report?). – Brian Cain Apr 25 '14 at 21:21
  • @BrianCain: Agree, but after seeing the AIX library, I got curious if something similar exists for linux. I guess I'll have to use `perf stat`. – brokenfoot Apr 25 '14 at 21:30
  • Dont lose hope, the reason there is no library in linux to do this is that it is trivial to do it without, please see my answer below. – Vality Apr 25 '14 at 22:46

3 Answers3

6

If you are running on Linux, you can use the perf_event_open system call (used by perf stat). It's a little bit tricky to get the right parameters, look at the man page http://web.eece.maine.edu/~vweaver/projects/perf_events/perf_event_open.html and see the code below.

There is no lib C wrapper so you have to call it as following:

static long perf_event_open(struct perf_event_attr *hw_event,
                pid_t pid,
                int cpu,
                int group_fd,
                unsigned long flags) {
  int ret = syscall(__NR_perf_event_open, hw_event, pid, cpu,
            group_fd, flags);
  return ret;
}

and then to count page faults:

  struct perf_event_attr pe_attr_page_faults;
  memset(&pe_attr_page_faults, 0, sizeof(pe_attr_page_faults));
  pe_attr_page_faults.size = sizeof(pe_attr_page_faults);
  pe_attr_page_faults.type =   PERF_TYPE_SOFTWARE;
  pe_attr_page_faults.config = PERF_COUNT_SW_PAGE_FAULTS;
  pe_attr_page_faults.disabled = 1;
  pe_attr_page_faults.exclude_kernel = 1;
  int page_faults_fd = perf_event_open(&pe_attr_page_faults, 0, CPU, -1, 0);
  if (page_faults_fd == -1) {
    printf("perf_event_open failed for page faults: %s\n", strerror(errno));
    return -1;
  }

  // Start counting
  ioctl(page_faults_fd, PERF_EVENT_IOC_RESET, 0);
  ioctl(page_faults_fd, PERF_EVENT_IOC_ENABLE, 0);

  // Your code to be profiled here 
  .....

  // Stop counting and read value
  ioctl(page_faults_fd, PERF_EVENT_IOC_DISABLE, 0);
  uint64_t page_faults_count;
  read(page_faults_fd, &page_faults_count, sizeof(page_faults_count));
Manuel Selva
  • 16,987
  • 21
  • 76
  • 127
3

It is not an API as such, however I have had a lot of success by rolling my own and reading /proc/myPID/stat from within my C program which includes page fault statistics for my process, this allows me to monitor counts in real time as my program runs and store these however I like.

Remember that doing so can cause page faults in itself so there will be some inaccuracy but you will get a general idea.

See here for details of the format of the file: https://access.redhat.com/site/documentation/en-US/Red_Hat_Enterprise_MRG/1.3/html/Realtime_Reference_Guide/chap-Realtime_Reference_Guide-Memory_allocation.html

Vality
  • 6,336
  • 3
  • 25
  • 47
3

There is getrusage function (SVr4, 4.3BSD. POSIX.1-2001; but not all fields are defined in standard). In linux there are several broken fields, but man getrusage lists several interesting fields:

long   ru_minflt;        /* page reclaims (soft page faults) */
long   ru_majflt;        /* page faults (hard page faults) */

long   ru_inblock;       /* block input operations */
long   ru_oublock;       /* block output operations */

The rusage is also reported in wait4 (only usable in external program). This one is used by /usr/bin/time program (it prints minor/major pagefault counts).

Community
  • 1
  • 1
osgx
  • 80,853
  • 42
  • 303
  • 470