Why clock_gettime() is faster than sysctl()?

Questions and Answers about all things *OS (macOS, iOS, tvOS, watchOS)

Why clock_gettime() is faster than sysctl()?

Postby wmm3416 » Wed Jan 16, 2019 9:56 am

In iOS10, clock_gettime() method is implemented, I tested clock_gettime and sysctl() to get device boot time. The code is as below.
Code: Select all
if (__builtin_available(iOS 10, *)) {
    struct timespec tp;
    if (clock_gettime(CLOCK_MONOTONIC, &tp) == 0) {
      return (int64_t)tp.tv_sec * 1000000 + tp.tv_nsec / 1000;
    }
  }


Code: Select all
struct timeval boottime;
  int mib[2] = {CTL_KERN, KERN_BOOTTIME};
  size_t size = sizeof(boottime);
  int kr = sysctl(mib, arraysize(mib), &boottime, &size, nullptr, 0);
  DCHECK_EQ(KERN_SUCCESS, kr);
  base::TimeDelta time_difference =
      base::Time::Now() - (base::Time::FromTimeT(boottime.tv_sec) +
                           base::TimeDelta::FromMicroseconds(boottime.tv_usec));
  return time_difference.InMicroseconds();


I found that clock_gettime is many times faster than sysctl in CPU cost. I'm curious about why clock_gettime is faster than sysctl. Does anyone know the specific reason, please?
Last edited by wmm3416 on Thu Jan 17, 2019 6:54 am, edited 1 time in total.
wmm3416
 
Posts: 6
Joined: Wed Jan 16, 2019 3:34 am

Re: Why clock_gettime() is faster than sysctl()?

Postby b3ntx » Wed Jan 16, 2019 2:49 pm

I think it's your normalization of the result from sysctl.

Code: Select all
struct timeval boottime, tod_tv, rel_tv,
              cgt_tv; /* <-- to convert timespec cgt to a timeval */
struct timespec cgt; // for clock_gettime()

// clock_gettime() to populate cgt
// ...

// convert the timespec to a timeval (no loss in precision because clock_gettime() reports USEC, but converts it to NSEC)
TIMESPEC_TO_TIMEVAL(&cgt_tv, &cgt);

// sysctl to populate boottime
// ...

gettimeofday(&tod_tv, NULL);
timersub(&tod_tv, &boottime, &rel_tv);

// now cgt_tv and rel_tv should be very close (within ~100usec probably)
b3ntx
 
Posts: 13
Joined: Wed Dec 16, 2015 1:26 pm

Re: Why clock_gettime() is faster than sysctl()?

Postby wmm3416 » Thu Jan 17, 2019 6:56 am

Thanks for your answer. But I think you misunderstood what I mean "faster". It means clock_gettime() method cost less time than sysctl() in CPU cost.
wmm3416
 
Posts: 6
Joined: Wed Jan 16, 2019 3:34 am

Re: Why clock_gettime() is faster than sysctl()?

Postby morpheus » Thu Jan 17, 2019 9:51 pm

Calls such as clock_gettime() use the Comm page, which saves a system call and is hence faster. Q.v. Volume I, page 46:

Screen Shot 2019-01-17 at 4.28.40 PM.png
Screen Shot 2019-01-17 at 4.28.40 PM.png (441.36 KiB) Viewed 745 times


Incidentally (minor pedantic point) semantically your code for checking the return code is somewhat incorrect. KR and KERN_SUCCESS is for Mach traps, which clock_gettime isn't. It's a BSD style library call, which follows semantics of syscalls (0, -1 + errno). In this case it doesn't matter (KERN_SUCCESS = 0 anyway), but you should use the kr/KERN_SUCCESS for traps/MIG, and >=0 for success or < 0 (check errno) for BSD styles.
morpheus
Site Admin
 
Posts: 685
Joined: Thu Apr 11, 2013 6:24 pm

Re: Why clock_gettime() is faster than sysctl()?

Postby wmm3416 » Tue Feb 19, 2019 10:51 am

That helps!!! Thank you very much!
wmm3416
 
Posts: 6
Joined: Wed Jan 16, 2019 3:34 am


Return to Questions and Answers

Who is online

Users browsing this forum: No registered users and 3 guests