how is it possible to run a code in limited time? - julia

Is it possible to run a code in an interval of time? for example, there is a small function as follow:
function test(n)
A = rand(n, n)
b = rand(n)
end
How is it possible test code will be run for 5 second and then it will be stopped?
would you please help me?
Thanks very much.

Here is what you could do:
function test(n)
A = rand(n, n)
b = rand(n)
end
start_time = time_ns() #Gets current time in nano seconds
seconds = 5000000000 #converted 5 seconds to nano seconds.
#time begin
while time_ns() - start_time <= seconds:
test(1)
end
end
#Note this code is designed to provide the logic of implementing this idea and may or may not work in your case.
The hard part about this that I mentioned in my comment is all time-based things in programming are best effort cases and not absolute.
See some examples from the docs about time for reference or my example below:
julia> #time begin
sleep(0.3)
end
0.305428 seconds (9 allocations: 352 bytes)
julia>
Even though we said we wanted to sleep for 0.3 seconds, it really slept for ~0.305 seconds. This should hopefully illuminate the issue with trying to do this.
It may also be possible depending on what you are doing to use threads. If you only want to give a function 5 seconds to return a new value, you can call that function with a thread, and then check the variable that accepts the return value to see if it's been updated. If it hasn't in 5 seconds, you can kill the thread or move on potentially. Though, I am not 100% sure of this.

Related

How to increase Julia code performance by preventing memory allocation?

I am reading Julia performance tips,
https://docs.julialang.org/en/v1/manual/performance-tips/
At the beginning, it mentions two examples.
Example 1,
julia> x = rand(1000);
julia> function sum_global()
s = 0.0
for i in x
s += i
end
return s
end;
julia> #time sum_global()
0.009639 seconds (7.36 k allocations: 300.310 KiB, 98.32% compilation time)
496.84883432553846
julia> #time sum_global()
0.000140 seconds (3.49 k allocations: 70.313 KiB)
496.84883432553846
We see a lot of memory allocations.
Now example 2,
julia> x = rand(1000);
julia> function sum_arg(x)
s = 0.0
for i in x
s += i
end
return s
end;
julia> #time sum_arg(x)
0.006202 seconds (4.18 k allocations: 217.860 KiB, 99.72% compilation time)
496.84883432553846
julia> #time sum_arg(x)
0.000005 seconds (1 allocation: 16 bytes)
496.84883432553846
We see that by putting x into into the argument of the function, memory allocations almost disappeared and the speed is much faster.
My question are, can anyone explain,
why example 1 needs so many allocation, and why example 2 does not need as many allocations as example 1?
I am a little confused.
in the two examples, we see that the second time we run Julia, it is always faster than the first time.
Does that mean we need to run Julia twice? If Julia is only fast at the second run, then what is point? Why not Julia just do a compiling first, then do a run, just like Fortran?
Is there any general rule to preventing memory allocations? Or do we just always have to do a #time to identify the issue?
Thanks!
why example 1 needs so many allocation, and why example 2 does not need as many allocations as example 1?
Example 1 needs so many allocations, because x is a global variable (defined out of scope of the function sum_arg). Therefore the type of variable x can potentially change at any time, i.e. it is possible that:
you define x and sum_arg
you compile sum_arg
you redefine x (change its type) and run sum_arg
In particular, as Julia supports multiple threading, both actions in step 3 in general could happen even in parallel (i.e. you could have changed the type of x in one thread while sum_arg would be running in another thread).
So because after compilation of sum_arg the type of x can change Julia, when compiling sum_arg has to ensure that the compiled code does not rely on the type of x that was present when the compilation took place. Instead Julia, in such cases, allows the type of x to be changed dynamically. However, this dynamic nature of allowed x means that it has to be checked in run-time (not compile time). And this dynamic checking of x causes performance degradation and memory allocations.
You could have fixed this by declaring x to be a const (as const ensures that the type of x may not change):
julia> const x = rand(1000);
julia> function sum_global()
s = 0.0
for i in x
s += i
end
return s
end;
julia> #time sum_global() # this is now fast
0.000002 seconds
498.9290555615045
Why not Julia just do a compiling first, then do a run, just like Fortran?
This is exactly what Julia does. However, the benefit of Julia is that it does compilation automatically when needed. This allows you for a smooth interactive development process.
If you wanted you could compile the function before it is run with the precompile function, and then run it separately. However, normally people just run the function without doing it explicitly.
The consequence is that if you use #time:
The first time you run a function it returns you both execution time and compilation time (and as you can see in examples you have pasted - you get information what percentage of time was spent on compilation).
In the consecutive runs the function is already compiled so only execution time is returned.
Is there any general rule to preventing memory allocations?
These rules are exactly given in the Performance Tips section of the manual that you are quoting in your question. The tip on using #time is a diagnostic tip there. All other tips are rules that are recommended to get a fast code. However, I understand that the list is long so a shorter list that is good enough to start with in my experience is:
Avoid global variables
Avoid containers with abstract type parameters
Write type stable functions
Avoid changing the type of a variable

Julia: waited longer than #time

I am trying to do in parallel some stuff. Based on #time the performance is excellent, but I am actually waiting quite long in front of my computer.
The code is something like below.
function max(n)
rand_n = SharedArray{Float64}(n, n)
#distributed for i in 1:n
#distributed for j in 1:n
r = Random(Uniform(), 100)
rand_n[i,j] = StatsBase.maximum(EV0)
end
end
rand_n
end
#time max(1000)
0.000166 seconds (118 allocations: 18.203 KiB)
tick()
max(1000)
tock()
2.865833086s: 2 seconds, 865 milliseconds
So the actual time elapsed on the computer is much longer that what #time says.
You should read the documentation of #distributed (type ?#distributed at the prompt):
Note that without a reducer function, #distributed executes
asynchronously, i.e. it spawns independent tasks on all available
workers and returns immediately without waiting for completion. To
wait for completion, prefix the call with #sync, like :
#sync #distributed for var = range
body
end
Currently, you are just starting the calculation and bailing out, so you get the timing of starting the calculation without waiting for it to finish.
A couple of more things:
Please always provide a "minimal working example" so that other posters can just copy-paste your code, and it will run. So include using Distributed and other required packages. Define all variables, etc. What is EV0, what does Random mean here? etc. etc.
You're defining r but you're not using it. What's it for?
max is the name of a function in Base, it's probably not a good idea to overload that name like this.

QT optimize program to execute calculations at particular time intervals (Signal & QTimer elapsed)

Hi I have a file with following format where am trying to calculate the position of aircraft from radar (approaching airport) every 10 msecs.
Position_X
Position_Y
Heading
Speed
t1
t2 w1
t3 w2
t4
Where w1, w2 = turn rate
in this case {t1, t2, t3, t4} = 200secs ~ 200000 msecs
and evaluating position after every 10 msecs
This is how am processing:
// defined in Plane.h
QElapsedTimer t;
QTimer timer;
// Plane.cpp
Plane::Plane : timer() {
QObject::connect(&timer, SIGNAL(timeout()), this, SLOT(computePosition()));
timer.start(10);
t.start();
}
void Plane::computePosition()
{
if (!t.hasExpired(t1)
{
//do
}
if (t.hasExpired(t2) || t.hasExpired(t3))
{
//do
}
if (t.hasExpired(t3) || t.hasExpired(t4))
{
// do
}
if (t.hasExpired(t5))
{
// do
}
if(t.hasExpired(t5 + 100))
timer.stop();
qDebug() << QDateTime::currentMSecsSinceEpoch()<< t.elapsed()
<< Position_X << Position_Y;
}
am not able to match system time with elapsed time or condition time. timer interval rate is 10 ms but in debug I see it varies from 15-40 secs. And also the approach time is 200 ms but with using elapsed timer to evaluate position pushes the plane matrix way out of the airport.
How do I make sure my program is running at time intervals t1, t2, t3, t4 & t5 and position is evaluated correctly.
Appreciate any ideas or help. Thanks!
Calculation of positions is not a problem.I want to do the calculations at time t1..t5 in conjugation with QTimer (interval is 10 ms).
First of all, you don't need to use timers to do calculations: you can precalculate everything in advance, the calculations use a time variable that doesn't need to be coupled to any timer. It's just a variable you increment as you execute steps of a numerical integration. You have to tell us why you think that the program has to run at some intervals - because thus far it's simply false. It's hardly even a Qt problem, it's plain old numerical methods. The calculations are simple; for every time step:
Start at t=0.
Update heading according to current turn rate.
Convert radial speed to cartesian speed.
Integrate speed into position.
Select next turn rate if current t is past given t_i.
Increment t by 10ms.
Repeat from #2 unless current time t is past end time.
That's it. You're free to choose whatever integration rule you want. t is just a variable. It doesn’t have anything to do with passage of time on the computer that computes the results.
The rest depends on what is the meaning of the times t1-t4, and what are the outputs you're looking for - whether you want time time history from starting position until some time t4+0.1s, or just 4 outputs - one for each time t1-t4, etc.
QTimer most likely won't be able to maintain strict 10 ms ticks. QElapsedTimer can be more accurate, but it's meant more to measure performance of functions, methods, etc.
If you want to simulate an interval of X ms, just set up the QTimer to fire at a particular interval. Then, you can maintain a counter that increments each time the timeout signal is emitted. From there, you can calculate your "simulated time", which would be T = X * count. There's no need for a QElapsedTimer at all.
QTimer isn't "hard real-time". If you absolutely must have hard real-time, you'll have to look elsewhere.

vecdot generates many allocations when inserting result into an array

This came up in other, more complex, code but I've written what I think is a minimum working example.
I found this behaviour surprising:
function byvecdot!(a,b,c)
for i in eachindex(a)
a[i] = vecdot(b[:,i],c[:,i])
end
return
end
function byiteration!(a,b,c)
for i in eachindex(a)
a[i] = 0.0
for j in 1:size(b,1)
a[i] += b[j,i]*c[j,i]
end
end
return
end
a = zeros(Float64,1000)
b = rand(Float64,1000,1000)
c = rand(Float64,1000,1000)
#time byvecdot!(a,b,c)
fill!(a,0.0) # Just so we have exactly the same environment
#time byiteration!(a,b,c)
Results (after warming up the JIT):
0.089517 seconds (4.98 k allocations: 15.549 MB, 88.70% gc time)
0.003165 seconds (4 allocations: 160 bytes)
I'm more surprised by the number of allocations than the time (the former is surely causing the latter, particularly given all the gc time).
I expected vecdot to be more or less the same as doing it by iteration (with a few extra allocations for length checks etc).
Making this more confusing: when I use vecdot by itself (even on slices/views/subarrays/whatever-they-are-called like b[:,i]), without inserting the result into an array element, it does behave basically the same as by iteration. I looked at the source code in Julia base and, no surprise, vecdot is just iterating over and accumulating up the result.
My question is: Can someone explain to me why vecdot generates so many (unnecessary) allocations when I try to insert it into an array element? What mechanics am I failing to grasp here?
b[:,i] allocates a new Array object so there is a big difference between the two versions. The first version creates many temporaries that the GC will have to track and free. An alternative solution is
function byvecdot2!(a,b,c)
for i in eachindex(a)
a[i] = vecdot(view(b,:,i),view(c,:,i))
end
return
end
The views also allocate but much less than the full copy that b[:,1] creates so the GC will do less work.

How to verify number of function evaluations when profiling R code

When profiling R code with Rprof-type functions we get the time spent in function alone and the time spent in function and callees. However, as far as I know we don't get the number of times a given function was evaluated.
For example, assume I wants to compare two integration functions:
integrate_1(myfunc, from = -Inf, to = Inf)
integrate_2(myfunc, from = -Inf, to Inf)
I could easily see how much time each function takes and where this time was spent, but I don't know how to check how many times myfunc had to be evaluated in each of the integrate functions.
Thanks,
One way of implementing Joran's counter method is to use the trace function.
For example, first we set the counter to zero. (Assigned in the global environment, for convenience.)
count <- 0
Then set up the trace. Here we set it on the identity function (that just returns the value that you input to it).
trace("identity", quote(count <<- count + 1), print = FALSE)
Now whenever identity is called, the value of count is incremented. print = FALSE just stops a message being printed to the console when the function is called.
Let's call the function a few times and inspect the count:
for(i in seq_len(123)) identity(1)
count
## [1] 123
Rprof works by sampling the call stack on a timer. It does not count calls.
It records the sampled call stacks in a file, and though it does not record line numbers where calls occur, those samples are still useful for seeing what causes time to be spent.
For example, if you happen to look at M random samples, and you see a pattern like A calling B calling C on N of them, then you know the program spends roughly fraction N/M of its time doing that (assuming N > 1).
If you see such a thing, and you can think of a way to avoid even part of it, you will save a substantial fraction of the total time.
Rprof comes with a summarization tool that gives you the kind of numbers you mentioned, but I don't find those numbers useful anyway.
I would much rather get a real sense of what's happening.

Resources