tachsin
tachsin

Reputation: 174

How to measure the @async runtime of functions in Julia?

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

Answers (3)

Przemyslaw Szufel
Przemyslaw Szufel

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

Andrej Oskin
Andrej Oskin

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

Jun Tian
Jun Tian

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

Related Questions