Undocumented Matlab
  • SERVICES
    • Consulting
    • Development
    • Training
    • Gallery
    • Testimonials
  • PRODUCTS
    • IQML: IQFeed-Matlab connector
    • IB-Matlab: InteractiveBrokers-Matlab connector
    • EODML: EODHistoricalData-Matlab connector
    • Webinars
  • BOOKS
    • Secrets of MATLAB-Java Programming
    • Accelerating MATLAB Performance
    • MATLAB Succinctly
  • ARTICLES
  • ABOUT
    • Policies
  • CONTACT
  • SERVICES
    • Consulting
    • Development
    • Training
    • Gallery
    • Testimonials
  • PRODUCTS
    • IQML: IQFeed-Matlab connector
    • IB-Matlab: InteractiveBrokers-Matlab connector
    • EODML: EODHistoricalData-Matlab connector
    • Webinars
  • BOOKS
    • Secrets of MATLAB-Java Programming
    • Accelerating MATLAB Performance
    • MATLAB Succinctly
  • ARTICLES
  • ABOUT
    • Policies
  • CONTACT

tic / toc – undocumented option

May 22, 2009 15 Comments

I have recently discussed undocumented features in Matlab’s built-in profiler. Another tool often used for ad-hoc performance profiling of Matlab code are the built-in duo functions tic and toc:

>> tic; magic(500); toc
Elapsed time is 0.474647 seconds.

Both tic and toc are documented functions, but they contain an undocumented option (at least until R2008b – see history below) that enables nested clocking. The problem that is solved using this undocumented option is that if we try to use tic/toc in external function parentFcn and also in the internal function childFcn, we get unexpected results. This happens because our childFcn‘s invocation of tic has reset the clock and so parentFcn‘s clock is now obviously incorrect:

function parentFcn
    % Start clocking
    tic;
    % Do something long...
    m1 = magic(1500);
    % Call nested function
    toc1 = childFcn;
    % Present clock timing
    toc2 = toc;
    fprintf('Elapsed time for childFcn:  %0.3f secs\n',toc1)
    fprintf('Elapsed time for parentFcn: %0.3f secs\n',toc2)
    % Nested function with separate clocking
    function t = childFcn
        tic;
        m = magic(800);
        t = toc;
    end  % childFcn
end  % parentFcn

function parentFcn % Start clocking tic; % Do something long... m1 = magic(1500); % Call nested function toc1 = childFcn; % Present clock timing toc2 = toc; fprintf('Elapsed time for childFcn: %0.3f secs\n',toc1) fprintf('Elapsed time for parentFcn: %0.3f secs\n',toc2) % Nested function with separate clocking function t = childFcn tic; m = magic(800); t = toc; end % childFcn end % parentFcn

>> parentFcn
Elapsed time for childFcn:  1.063 secs
Elapsed time for parentFcn: 1.068 secs

The solution: use a separate handle for each clock. The format is very simple:

>> t = tic;
>> toc(t)

This format ensures independent clocking of the clocks. Clockings can now be safely nested and even partial overlap is possible:

function parentFcn
    % Start clocking
    t1 = tic;
    % Do something long...
    m1 = magic(1500);
    % Call nested function
    toc1 = childFcn;
    % Present clock timing
    toc2 = toc(t1);
    fprintf('Elapsed time for childFcn:  %0.3f secs\n',toc1)
    fprintf('Elapsed time for parentFcn: %0.3f secs\n',toc2)
    % Nested function with separate clocking
    function t = childFcn
        tic;
        m = magic(800);
        t = toc;
    end  % childFcn
end  % parentFcn

function parentFcn % Start clocking t1 = tic; % Do something long... m1 = magic(1500); % Call nested function toc1 = childFcn; % Present clock timing toc2 = toc(t1); fprintf('Elapsed time for childFcn: %0.3f secs\n',toc1) fprintf('Elapsed time for parentFcn: %0.3f secs\n',toc2) % Nested function with separate clocking function t = childFcn tic; m = magic(800); t = toc; end % childFcn end % parentFcn

>> parentFcn
Elapsed time for childFcn:  1.123 secs
Elapsed time for parentFcn: 4.992 secs

For the record, this undocumented option was first presented by the MathWorks support team as an official workaround for the aforementioned problem. The solution was originally posted for Matlab R2006b, but actually the option was supported by Matlab versions at least as early as R14SP3 (7.1) – perhaps even earlier (I don’t have ready access to earlier versions). I do know that it was not supported on release R12 aka 6.0, but I don’t know whether it was introduced in 6.5, 7.0 or 7.1. This option has only been documented since R2008b, although it has existed in many earlier releases.
Now here’s a puzzle for all you undoc fans out there: toc has a really undocumented option of using an uninitialized uint64 value, rather than an actual tic handle. It seems that whichever value is passed will always result in the same result, but this result is uncorrelated to any possible event (start of Matlab, midnight etc.). It even works without any prior tic invocation! I would love to hear your thoughts on what you think this strange toc result might represent:

>> toc(uint64(1))
Elapsed time is 72825.947547 seconds.
>> toc(uint64(1234))
Elapsed time is 72826.538296 seconds.

Related posts:

  1. Buggy Profiler option – a bug exists in the profiler that prevents usage of its documented CPU timing functionality. ...
  2. Undocumented Profiler options part 3 – An undocumented feature of the Matlab Profiler can report call history timeline - part 3 of series. ...
  3. Undocumented Profiler options part 4 – Several undocumented features of the Matlab Profiler can make it much more useful - part 4 of series. ...
  4. More undocumented timing features – There are several undocumented ways in Matlab to get CPU and clock data...
  5. Undocumented plot marker types – Undocumented plot marker styles can easily be accesses using a hidden plot-line property. ...
  6. ishghandle's undocumented input parameter – The built-in function ishghandle accepts a second input argument with the expected handle type....
Performance Pure Matlab Undocumented feature
Print Print
« Previous
Next »
15 Responses
  1. Jason McMains May 22, 2009 at 07:51 Reply

    I believe the undocumented toc(uint64(1)) option is connected to the last time you restarted your computer. I ran this function twice. Once before I restarted and once after. The number before restart was the equivalent to about 72 hours, the number after was about 3 minutes.

    • Yair Altman May 22, 2009 at 07:58 Reply

      You must be right Jason – this also correlates with the number I posted above. Good catch!

  2. Petter May 22, 2009 at 09:35 Reply

    It is equal to the uptime of my computer.

  3. Petter May 22, 2009 at 09:42 Reply

    The value returned by tic is not a handle. It is just a counter with some native time step.

    On my computer, one tic is 6.9836e-008 seconds, according to my measurements. This internal counter starts at 0 when the computer starts.

  4. Alessandro Giusti May 22, 2009 at 13:03 Reply

    I think that the uint64 number returned by tic is the number of microseconds after the system started. It is also the most straightforward way to implement such tic/toc mechanism.

    The usual behavior of other functions, instead, made me initially think of the value being some sort of handle to internal data, which is probably not. 🙂

    This is confirmed by a couple of tests (at least under linux):

    >> a=tic; pause(1); b=tic;
    >> disp(double(b)-double(a))
    1000624

    >> a=tic; pause(2); b=tic;
    >> disp(double(b)-double(a))
    2000627

    … and also:
    >> a=tic; pause(1); toc(uint64(double(a)+1))
    Elapsed time is 1.000410 seconds.

    A partly unrelated note:

    >> uint64(1)+uint64(2)
    ??? Undefined function or method ‘plus’ for input arguments of type ‘uint64’.

    Why?!?

    • Petter May 25, 2009 at 23:41 Reply

      It is not the number of microseconds on Windows. It has a higher resolution than that.

  5. shabby June 2, 2009 at 10:45 Reply

    tic appears to return the number of microseconds since the epoch, at least on my r2007b install on 64 bit linux:

    >> [a,retv_pre] = system(‘date +”%s”’);ticv = tic();[a,retv_post] = system(‘date +”%s”’);retv_avg = 0.5 * (str2num(retv_pre) + str2num(retv_post));retv_avg – (double(ticv) / 1e6)

    ans =

    -0.5501

  6. Cris September 28, 2009 at 02:14 Reply

    TIC/TOC has had this option for a long time. I seem to remember it in the MATLAB 5.3 days, but I might be wrong.

    TIC sets a local persistent variable to the current time. TOC returns the difference between that time and the current time. The value T=TIC just returns the current time, without resetting the local variable. TOC(T) then returns the difference between T and the current time. If T is larger than the current time, it uses the local variable. That is, it ignores its input. How the “current time” is defined could depend on the system, though. I wouldn’t count on it being the time since the computer last rebooted.

    Oh, I should have checked earlier. I’m just now looking at HELP TIC and HELP TOC. This feature is documented in R2009a. 🙂

  7. Andrew Janke September 7, 2010 at 14:05 Reply

    Looks system dependent. On R2009b, R2010a, and R2010b on Windows, I think the tic() unit is the number of CPU clock cycles since the computer’s last boot time. (Not active CPU time, just time counted in the CPU’s clock period.) YMMV, of course. Petter’s tic speed number looks different.

    for i = 1:2:10;
       t0 = double(tic);
       pause(i); 
       t1 = double(tic); 
       dt = t1-t0; 
       per_sec = dt./i; 
       fprintf('dt = %g   per_sec = %gn', dt, per_sec); 
    end

    for i = 1:2:10; t0 = double(tic); pause(i); t1 = double(tic); dt = t1-t0; per_sec = dt./i; fprintf('dt = %g per_sec = %gn', dt, per_sec); end

    That results in about 2.84e+009, 3.0e+009 and 3.15e+009 “tic units” per second on the 2.83, 3.0 and 3.16 GHz Windows XP and Server 2003 machines I tested it on.

    Plug in your machine’s clock speed and you get the uptime.

    ghz = 3.0; uptime = round(double(tic) ./ (ghz * 10^9 * 60))

    ghz = 3.0; uptime = round(double(tic) ./ (ghz * 10^9 * 60))

  8. Helge August 30, 2011 at 20:14 Reply

    Version compatibility issue(1):

    Maybe R11 had tic/toc with options (as reported above), I don’t remember. However, R13 does NOT.
    So take care if you must guarantee downward compatibility.

    Version compatibility issue(2):

    @Alessandro Giusti:
    >> uint64(1)+uint64(2)
    ??? Undefined function or method ‘plus’ for input arguments of type ‘uint64′.
    Why?!?

    Response: help text says: UINT64 is primarily meant to store integer values, and math operations are
    NOT defined since they are ambiguous on the boundary of the set (e.g., wrap or truncate there)
    UINT32 has (had?) less but essentially similar restrictions, for good reasons.

    I recognized some inconsistencies between UINT8/16/32/64 regarding the allowed basic math operations
    (plus, times). Math support has been improved in versions after R13 but seems still kind of crappy and
    –my personal opinion– even more inconsistent than in R13. Depending on the Matlab version, stuff like
    uint32(32)+double(rand) can yield errors or uint32(round(32+rand)), i.e., one can neither rely on errors
    nor expect an implicit type conversion to double as in C/C++

    Frankly, I dont care any longer whether this has changed in new releases — I simply avoid uint classes
    completely except for raw binary file IO or to check input arguments, e.g., using isequal(x,uint16(x)).

    And regarding the use of uint64 as a counter/hashcode/handle: just try

    >> tic, for n=1:2^16, k=uint64(n); end; toc

    >> tic, for n=1:2^16, k=uint64(n); end; toc

    and extrapolate the number of days required until the loop would stop for n=1:2^64.

    I guess that toc apparently returns UINT64 not because 64 bit precision were technically necessary
    or would simplify follow-up operations in Matlab, but rather because UINT64 is what Java or OS library
    functions natively return to Matlab, and because Matlab’s tic/toc do not want to waste any time for
    type conversion and out-of-range checking/mapping. This leads me to the conclusion that tic/toc should
    be potentially more precise than t0=now; … dt=now-t0; because NOW definitely requires some algorithmic
    overhead.

    Can anybody (in)validate these conclusions?

    Cheers, H;

    • Donn Shull August 31, 2011 at 11:16 Reply

      This won’t shed any new light on tic and toc but I noted in my post on UDD properties that despite having a large array of data types available for a UDD property unsigned integer types were conspicuously absent.

  9. Tobias Schäfer October 8, 2012 at 02:16 Reply

    It is the value of a counter operating incrementing with the clock speed of the computer. This line returns the speed of Your machine in Hz:

    >> clk = 1e12 /( toc(uint64(0)) - toc(uint64(1e12)) )
    clk =
      2.9925e+009

    >> clk = 1e12 /( toc(uint64(0)) - toc(uint64(1e12)) ) clk = 2.9925e+009

    Press [Windows Key]+[Pause] to check. (Tested on Microsoft Windows XP)

  10. Tobias Schäfer October 8, 2012 at 02:45 Reply

    This might also be used to get the time when the computer was started:

    tStart = now - toc(uint64(0))/(60*60*24);
    fprintf(1,['This computer was started at ', datestr(tStart), '.n']);

    tStart = now - toc(uint64(0))/(60*60*24); fprintf(1,['This computer was started at ', datestr(tStart), '.n']);

  11. Peto December 14, 2014 at 21:39 Reply

    Can you help me!!!
    I want use “tic/toc” or “etime clock” for this code but I don’t know how I make exactly.

    [very long code snip…]

    I will appreciate if you help me.
    thank before!

    • Yair Altman December 15, 2014 at 00:44 Reply

      @Peto – this is not the right forum for such questions. Try the Answers forum.

Leave a Reply
HTML tags such as <b> or <i> are accepted.
Wrap code fragments inside <pre lang="matlab"> tags, like this:
<pre lang="matlab">
a = magic(3);
disp(sum(a))
</pre>
I reserve the right to edit/delete comments (read the site policies).
Not all comments will be answered. You can always email me (altmany at gmail) for private consulting.

Click here to cancel reply.

Useful links
  •  Email Yair Altman
  •  Subscribe to new posts (feed)
  •  Subscribe to new posts (reader)
  •  Subscribe to comments (feed)
 
Accelerating MATLAB Performance book
Recent Posts

Speeding-up builtin Matlab functions – part 3

Improving graphics interactivity

Interesting Matlab puzzle – analysis

Interesting Matlab puzzle

Undocumented plot marker types

Matlab toolstrip – part 9 (popup figures)

Matlab toolstrip – part 8 (galleries)

Matlab toolstrip – part 7 (selection controls)

Matlab toolstrip – part 6 (complex controls)

Matlab toolstrip – part 5 (icons)

Matlab toolstrip – part 4 (control customization)

Reverting axes controls in figure toolbar

Matlab toolstrip – part 3 (basic customization)

Matlab toolstrip – part 2 (ToolGroup App)

Matlab toolstrip – part 1

Categories
  • Desktop (45)
  • Figure window (59)
  • Guest bloggers (65)
  • GUI (165)
  • Handle graphics (84)
  • Hidden property (42)
  • Icons (15)
  • Java (174)
  • Listeners (22)
  • Memory (16)
  • Mex (13)
  • Presumed future risk (394)
    • High risk of breaking in future versions (100)
    • Low risk of breaking in future versions (160)
    • Medium risk of breaking in future versions (136)
  • Public presentation (6)
  • Semi-documented feature (10)
  • Semi-documented function (35)
  • Stock Matlab function (140)
  • Toolbox (10)
  • UI controls (52)
  • Uncategorized (13)
  • Undocumented feature (217)
  • Undocumented function (37)
Tags
AppDesigner (9) Callbacks (31) Compiler (10) Desktop (38) Donn Shull (10) Editor (8) Figure (19) FindJObj (27) GUI (141) GUIDE (8) Handle graphics (78) HG2 (34) Hidden property (51) HTML (26) Icons (9) Internal component (39) Java (178) JavaFrame (20) JIDE (19) JMI (8) Listener (17) Malcolm Lidierth (8) MCOS (11) Memory (13) Menubar (9) Mex (14) Optical illusion (11) Performance (78) Profiler (9) Pure Matlab (187) schema (7) schema.class (8) schema.prop (18) Semi-documented feature (6) Semi-documented function (33) Toolbar (14) Toolstrip (13) uicontrol (37) uifigure (8) UIInspect (12) uitable (6) uitools (20) Undocumented feature (187) Undocumented function (37) Undocumented property (20)
Recent Comments
Contact us
Captcha image for Custom Contact Forms plugin. You must type the numbers shown in the image
Undocumented Matlab © 2009 - Yair Altman
This website and Octahedron Ltd. are not affiliated with The MathWorks Inc.; MATLAB® is a registered trademark of The MathWorks Inc.
Scroll to top