|
When running statements within Magma in serial mode only, using the
CPU time to measure the time taken between one or more statements
is reasonable and accurate. In particular, one can: (1) use the time
statement; (2) call the function Cputime() which returns the
total CPU time (in seconds) taken by Magma since startup; (3) call the
function Cputime(T) to give the CPU time (in seconds) taken since
the variable T was last set to Cputime().
However, when parallelism is used with multiple threads and/or distributed
computation, the CPU time is not useful as a measure of the time taken,
since this the value which the kernel yields for this typically includes
the sum of the CPU time taken by all threads together with extra
overhead in the kernel handling, and this number can be skewed even
more if hyperthreading is present. So the real (wall-clock) time taken
is usually not related to the CPU time divided by the total number of
threads in any useful or accurate way. Also, in the distributed case,
the CPU time can only refer to threads running on the master node,
and not on worker nodes.
Consequently, the real (wall-clock) time taken by one or more statements
in Magma is the best way to measure the time taken when parallelism is present.
One way of obtaining this information is to call the function Realtime(T) to give the real time taken (in seconds) since T was
last set to Realtime(). But it is easier just to use the time statement or the Time function, since these give useful
timing information no matter whether serial or parallelism is present
or not in any computation. These can be used as follows:
- (i)
- If time is placed before a statement and a
multi-threaded/distributed algorithm is not used within the executed
statement, then the CPU time alone is printed.
- (ii)
- If time is placed before a statement and
a multi-threaded/distributed algorithm is used within the executed
statement while the real time r taken is less than the CPU time
c taken, then the time printed is r, and the tag [r]
is appended (to indicate that the time printed is a real time);
otherwise the CPU time c is printed.
So one can know whether a multi-threaded/distributed algorithm has been used
within the executed statement: that is the case if and only if the
tag [r] is printed.
- (iii)
- The verbose time statement vtime has the same behaviour as time in the above two cases.
- (iiv)
- The function Time is used in a similar way to Cputime
and Realtime, while selecting their behaviour depending on
whether parallelism is used: after setting a variable such as T to
Time(), then after a series of statements, one can print the
value Time(T) (which is always a string) to give the lapsed
time since T was assigned. Just as for the time statement
above, the tag [r] is added if and only if the real time is
used in the second call to Time. So the presence of
that tag indicates that at least one multi-threaded/distributed
algorithm has been used between the calls to Time, while
the absence of the tag indicates that no parallelism was used
and the CPU time is returned by the Time function.
A simple example of the use of time and Time is the following.
> SetNthreads(1); // SERIAL (NO PARALLELISM)
> X := Random(MatrixRing(GF(5), 10000));
> time P := X*X; // serial only, so prints CPU time (seconds)
Time: 4.060
> T := Time(); P := X*X; Time(T); // same as what time statement prints
4.060
> SetNthreads(8); // PARALLEL (8 POSIX THREADS)
> time P := X*X; // parallel, so real time shown by [r] (seconds)
Time: 1.050[r]
> T := Time(); P := X*X; Time(T); // same as what time statement prints
1.050[r]
[Next][Prev] [Right] [Left] [Up] [Index] [Root]
|