bugGNU Octave - Bugs: bug #52858, Consider using C gnulib...

 
 

bug #52858: Consider using C gnulib clock_gettime() for Octave cputime()

Submitter:  Dan Sebald <sebald>
Submitted:  Wed 10 Jan 2018 05:34:19 PM UTC
   
 
Category:  Performance Severity:  3 - Normal
Priority:  5 - Normal Item Group:  Performance
Status:  None Assigned to:  None
Originator Name:  Open/Closed:  * Open
Release:  * dev Operating System:  * GNU/Linux
Fixed Release:  None Planned Release:  None
* Mandatory Fields

Add a New Comment Rich Markup
   

Jump to the original submission

Fri 12 Jan 2018 03:44:42 PM UTC, comment #7: 

The "resolution" of the time function is not the problem.
If it were, just running the test longer would fix it.

The problem is that, from the very beginning of UNIX days,
kernel processes are NOT interruptible. Therefore any
user process may take any amount of real-time. And,
the attempts measure and make available cpu-time are
affected in the same way. There is no predictable time
lapse in gaining access to the kernel time data.

The answer is the make multiple runs of the same (fairly
long) test and then choose a suitable "average." It can
be argued that the "best" choice is the minimum reported value.
This one will have been least affected by delays during
kernel processes. Keep in mind that read/write to I/O
devices are kernel processes so quite a few seconds can elapse
before anything else can happen to timing calls or anything
else.

This choice was made by the original Bell Labs UNIX folks
when they thought that what they were doing was building a
convenient, single-user, report writing system. The rest is
history...

Even running Linux as a virtual system under a controlling
system which does not use uninterruptible calls does not
fix the problem because the Linux call still has to block until
its results are returned. System efficiency is improved by
this choice, but it does not change the behavior of client
systems.

So, any of the timing routines can be chosen.

Michael Godfrey <godfrey>
Group Member
Fri 12 Jan 2018 12:48:04 AM UTC, comment #6: 

You're right. Dan's original issue is about using clock_gettime to provide cputime (process elapsed time) with nanosecond resolution. I interjected to comment that I would also like to use clock_gettime so that functions like time, clock, and now would also report nanosecond resolution. The clock_gettime function can do both wall clock time and process time, but it's not portable.

However this is done at the system level, it will also require API changes to octave::sys::base_tm, octave::sys::cpu_time, etc, in the oct-time.h header file to store nanoseconds.

Mike Miller <mtmiller>
Group Member
Fri 12 Jan 2018 12:39:52 AM UTC, comment #5: 

Oh.  I think I was confused by the summary of this report to think that we were talking about using clock_gettime to provide cputime.

In any case, if there isn't a gnulib module for a portability function, then I think we should try to add the wrapper to gnulib.  If that can't be done, I'd still like to isolate the portability decisions/wrappers in liboctave's wrapper directory.

John W. Eaton <jwe>
Group administrator
Fri 12 Jan 2018 12:31:48 AM UTC, comment #4: 

The last time I looked they are not provided by gnulib. Gnulib does provide some M4 autoconf code to check whether they are available, and add "-lrt" if necessary, which is what we are already using.

Gnulib does provide a function called "gettime" which calls either nanotime (BSD function?), clock_gettime (POSIX function), or gettimeofday. But this only works as a wall clock function, this wouldn't work as a replacement for process time as reported by getrusage for example.

Mike Miller <mtmiller>
Group Member
Fri 12 Jan 2018 12:21:40 AM UTC, comment #3: 

I think these functions are provided by gnulib, so I would prefer to use those and be able to just assume that they exist.  I do understand that it would require some wrapper functions for portability, but I would prefer to use those as we do for other functions instead of adding #ifdefs in liboctave or libinterp.

John W. Eaton <jwe>
Group administrator
Thu 11 Jan 2018 11:29:14 PM UTC, comment #2: 

Noting here that I would also like to look at using clock_gettime instead of gettimeofday on supported systems for a higher resolution wall clock value as well.

Both of these changes would need to affect the classes defined in liboctave/sys/oct-time.h, replacing all of the microsecond fields with nanosecond resolution fields.

Octave's configure script already checks for the existence of clock_gettime and clock_settime, so code only needs to use the HAVE_CLOCK_GETTIME macro already defined in config.h, as well as testing for the existence of whichever CLOCK_FOO is desired.

Mike Miller <mtmiller>
Group Member
Wed 10 Jan 2018 05:45:00 PM UTC, comment #1: 

Continuing from this post:

https://savannah.gnu.org/bugs/?52809#comment22

I've implemented the example loops with cputime and tic/toc as functions:


function tdiff=bm_for_loop()
a = 1; b = 1; t0=cputime; for i=1:1000; for j=1:1000; a = a + b + 123.0; end;
end; t1=cputime; tdiff = t1 - t0



function t1=bm_for_loop2()
a = 1; b = 1; t0=tic; for i=1:1000; for j=1:1000; a = a + b + 123.0; end; end;
t1=toc(t0); t1


As results, I'm seeing:


octave:9> tl=zeros(20,1); for i=1:20; tl(i) = bm_for_loop; end;
tdiff =  2.7720
tdiff =  2.8040
tdiff =  2.7960
tdiff =  2.8000
tdiff =  2.8000
tdiff =  2.8000
tdiff =  2.8000
tdiff =  2.8000
tdiff =  2.8160
tdiff =  2.8000
tdiff =  2.8000
tdiff =  2.7960
tdiff =  2.7960
tdiff =  2.8000
tdiff =  2.8000
tdiff =  2.8040
tdiff =  2.7960
tdiff =  2.8160
tdiff =  2.7960
tdiff =  2.8000
octave:10> tl2=zeros(20,1); for i=1:20; tl2(i) = bm_for_loop2; end;
t1 =  2.7467
t1 =  2.8181
t1 =  2.8147
t1 =  2.8200
t1 =  2.8073
t1 =  2.8180
t1 =  2.8186
t1 =  2.8184
t1 =  2.8127
t1 =  2.8237
t1 =  2.8149
t1 =  2.8078
t1 =  2.8130
t1 =  2.8135
t1 =  2.8145
t1 =  2.8168
t1 =  2.8243
t1 =  2.8114
t1 =  2.8069
t1 =  2.8138
octave:11> mean(tl)
ans =  2.7996
octave:12> std(tl)
ans =  0.0085987
octave:13> mean(tl2)
ans =  2.8118
octave:14> std(tl2)
ans =  0.016044
octave:15> mean(tl2) - mean(tl)
ans =  0.012160


I don't think I can conclude there is a statistically significant difference from that, given there could be slightly different CPU usage between invocations.

I do believe though that there could be a difference in the above link, statistically speaking, i.e.,


octave:1> bm_for_loop
ans =  4.6840
octave:2> bm_for_loop
ans =  4.6640
octave:3> bm_for_loop
ans =  4.6240
octave:4> bm_for_loop2
t1 =  4.4830
octave:5> bm_for_loop2
t1 =  4.5830
octave:6> bm_for_loop2
t1 =  4.4962


I wonder if the issue there is that, in fact, the test is physically taking less time to operate than what cputime() reports because cputime() might include a combination of CPU usage from more than one processor core.  That is, perhaps some small aspect of this test can be shifted to a second CPU in a multi-threaded environment.

Dan Sebald <sebald>
Wed 10 Jan 2018 05:34:19 PM UTC, original submission:  

There was a discussion in another bug that led to the question of whether Octave should use the clock_gettime() in cputime() rather than its current implementation, which I believe is getrusage():

https://savannah.gnu.org/bugs/?52809#comment21

Here is a list of all the pertinent comments in that thread, in reverse chronological order:

https://savannah.gnu.org/bugs/?52809#comment22
https://savannah.gnu.org/bugs/?52809#comment21
https://savannah.gnu.org/bugs/?52809#comment20
https://savannah.gnu.org/bugs/?52809#comment19
https://savannah.gnu.org/bugs/?52809#comment18
https://savannah.gnu.org/bugs/?52809#comment17
https://savannah.gnu.org/bugs/?52809#comment16
https://savannah.gnu.org/bugs/?52809#comment15
https://savannah.gnu.org/bugs/?52809#comment14
https://savannah.gnu.org/bugs/?52809#comment13

This is not a high priority, nor necessarily even an actual, bug.  So, this is more just a consideration at this point.

This is unix-based, and Mac OS might be included.  There is an "Update" to the winning post in this discussion:

https://stackoverflow.com/questions/12392278/measure-time-in-linux-time-vs-clock-vs-getrusage-vs-clock-gettime-vs-gettimeof

"Update: for OS X, clock_gettime has been implemented as of 10.12 (Sierra)."

Dan Sebald <sebald>

 

(Note: upload size limit is set to 16384 kB, after insertion of the required escape characters.)

Attach Files:
   
   
Comment:
   

No files currently attached

 

Depends on the following items: None found

Items that depend on this one: None found

 

Carbon-Copy List
  • -email is unavailable- added by godfrey (Posted a comment)
  • -email is unavailable- added by jwe (Posted a comment)
  • -email is unavailable- added by mtmiller (Posted a comment)
  • -email is unavailable- added by sebald (Submitted the item)
  •  

    There are 0 votes so far. Votes easily highlight which items people would like to see resolved in priority, independently of the priority of the item set by tracker managers.

    Only group members can vote.

     

    No changes have been made to this item

    Back to the top

    Powered by Savane 3.14-3b9d.
    Corresponding source code