Reputation: 174
My code is as the following,
function getImages()
@async for i in 1:30
load("path/to/image$i.jpg");
end
end
@time @sync getImages()
Is this the correct way to measure asynchronous runtime in Julia? I don't want to believe it because in synchronous run it takes 0.1 seconds to finish and with the @async code it shows only 0.000017 seconds.
Upvotes: 3
Views: 195
Reputation: 42214
Here is the correct code:
function getImages()
myimages = Vector{Any}(undef, 30)
# instead of Any use the correct type of whatever your load returns
@sync for i in 1:30
@async myimages[i] = load("path/to/image$i.jpg");
end
myimages
end
This approach is usefull when your IO is slow. Note however that this coode is going to utilize only a single thread. Hence if not IO is your performance bottleneck such parallelization will not help. In that case you should consider using threads.
Before starting Julia run:
set JULIA_NUM_THREADS=4
or on Linux
export JULIA_NUM_THREADS=4
And change your function to:
function getImages()
myimages = Vector{Any}(undef, 30)
# instead of Any use the correct type of whatever your load returns
Threads.@threads for i in 1:30
myimages[i] = load("path/to/image$i.jpg");
end
myimages
end
Upvotes: 1
Reputation: 2332
You need to reorganize your code a little
julia> function getImages()
@sync for i in 1:30
@async begin
sleep(rand())
println("Image ", i)
end
end
end
getImages (generic function with 1 method)
julia> @time getImages()
Image 2
Image 5
Image 15
Image 30
Image 4
Image 7
Image 20
Image 3
Image 22
Image 18
Image 11
Image 29
Image 9
Image 24
Image 16
Image 6
Image 8
Image 14
Image 19
Image 21
Image 13
Image 1
Image 17
Image 10
Image 27
Image 25
Image 23
Image 28
Image 26
Image 12
0.894566 seconds (650 allocations: 37.406 KiB)
Upvotes: 2
Reputation: 1390
Your intuition is right here! The short answer is that you're not using @sync
correctly.
Quote from the doc of @sync
:
Wait until all lexically-enclosed uses of @async, @spawn, @spawnat and @distributed are complete. All exceptions thrown by enclosed async operations are collected and thrown as a CompositeException.
Here the @async
is NOT lexically-enclosed in the @sync
expression. Actually there's no magic in the @sync
macro. The @async
, @spawn
, @spawnat
and @distributed
expressions will create tasks. And @sync
simply wait for them to finish.
So you manually do it like this:
julia> f() = @async sleep(1)
julia> @time wait(f())
1.002095 seconds (9 allocations: 848 bytes)
Upvotes: 1