Multiple threading
The multi-threading computation is built upon Julia's @threads macro.
Base.Threads.@threads for ... endIt provides an OpenMP type parallelization. The iteration space is splitted among multiple tasks and those tasks are parallelized on threads according to a scheduling policy. A barrier is placed at the end of the loop which waits for all tasks to finish execution.
In Kinetic, @threads is set in front of the loops for reconstruction, evolution and update. For example, the evaluation of fluxes is conducted as follows.
@inbounds Threads.@threads for i = idx0:idx1
flux_gks!(
face[i].fw,
ctr[i-1].w .+ 0.5 .* ctr[i-1].dx .* ctr[i-1].sw,
ctr[i].w .- 0.5 .* ctr[i].dx .* ctr[i].sw,
KS.gas.γ,
KS.gas.K,
KS.gas.μᵣ,
KS.gas.ω,
dt,
0.5 * ctr[i-1].dx,
0.5 * ctr[i].dx,
ctr[i-1].sw,
ctr[i].sw,
)
endIt automatically makes use of multiple threading if Julia is initialized with
julia -t nBesides of @threads, finer dispatch can be made with @spawn macro.
Base.Threads.@spawnIt creates and runs a task on any available thread. To wait for the task to finish, call wait on the result of this macro, or call fetch to wait and then obtain its return value. Values can be interpolated into @spawn via $, which copies the value directly into the constructed underlying closure. It allows user to insert the value of a variable, isolating the aysnchronous code from changes to the variable's value in the current task. This can be conduct with the low-level reconstruction, flux and step functions.