From e0a4cff1115967964809bd4a528d7c4eb2c7109d Mon Sep 17 00:00:00 2001 From: Carsten Bauer Date: Fri, 2 Feb 2024 13:54:14 +0100 Subject: [PATCH 1/4] translation page for docs --- docs/make.jl | 2 + docs/src/translation.md | 119 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 121 insertions(+) create mode 100644 docs/src/translation.md diff --git a/docs/make.jl b/docs/make.jl index 12c8760e..94024cfb 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -12,6 +12,8 @@ makedocs(; doctest = false, pages = [ "OhMyThreads" => "index.md", + # "Getting Started" => "examples/getting_started.md", + "Translation" => "translation.md", "Examples" => [ "Parallel Monte Carlo" => "examples/mc/mc.md", "Julia Set" => "examples/juliaset/juliaset.md", diff --git a/docs/src/translation.md b/docs/src/translation.md new file mode 100644 index 00000000..67a30364 --- /dev/null +++ b/docs/src/translation.md @@ -0,0 +1,119 @@ +# Translation + +## Basic + +### `@threads` + +```julia +# Base.Threads +@threads for i in 1:10 + println(i) +end +``` + +```julia +# OhMyThreads +tforeach(1:10) do i + println(i) +end +``` + +#### `:static` scheduling + +```julia +# Base.Threads +@threads :static for i in 1:10 + println(i) +end +``` + +```julia +# OhMyThreads +tforeach(1:10; schedule=:static) do i + println(i) +end +``` + +### `@spawn` + +```julia +# Base.Threads +@sync for i in 1:10 + @spawn println(i) +end +``` + +```julia +# OhMyThreads +tforeach(1:10; nchunks=10) do i + println(i) +end +``` + +## Reduction + +No built-in feature in Base.Threads. + +```julia +# Base.Threads: basic manual implementation +data = rand(10) +chunks_itr = Iterators.partition(data, length(data) รท nthreads()) +tasks = map(chunks_itr) do chunk + @spawn reduce(+, chunk) +end +reduce(+, fetch.(tasks)) +``` + +```julia +# OhMyThreads +data = rand(10) +treduce(+, data) +``` + +## Mutation + +TODO: Remark why one has to be careful here (e.g. false sharing). + +```julia +# Base.Threads +data = rand(10) +@threads for i in 1:10 + data[i] = calc(i) +end +``` + +```julia +# OhMyThreads: Variant 1 +data = rand(10) +tforeach(data) do i + data[i] = calc(i) +end +``` + +```julia +# OhMyThreads: Variant 2 +data = rand(10) +tmap!(data, data) do i # TODO: comment on aliasing + calc(i) +end +``` + +## Parallel initialization + +```julia +# Base.Threads +data = Vector{Float64}(undef, 10) +@threads for i in 1:10 + data[i] = calc(i) +end +``` + +```julia +# OhMyThreads: Variant 1 +data = tmap(i->calc(i), 1:10) +``` + +```julia +# OhMyThreads: Variant 2 +data = tcollect(calc(i) for i in 1:10) +``` \ No newline at end of file From e31e11b9b408c8bd00b4fbd49f15252deccc9d86 Mon Sep 17 00:00:00 2001 From: Carsten Bauer Date: Fri, 2 Feb 2024 14:24:30 +0100 Subject: [PATCH 2/4] minor improvements --- docs/make.jl | 2 +- docs/src/refs/api.md | 2 +- docs/src/translation.md | 8 ++++++-- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/docs/make.jl b/docs/make.jl index 94024cfb..91f343b9 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -13,7 +13,6 @@ makedocs(; pages = [ "OhMyThreads" => "index.md", # "Getting Started" => "examples/getting_started.md", - "Translation" => "translation.md", "Examples" => [ "Parallel Monte Carlo" => "examples/mc/mc.md", "Julia Set" => "examples/juliaset/juliaset.md", @@ -21,6 +20,7 @@ makedocs(; # "Explanations" => [ # "B" => "explanations/B.md", # ], + "Translation Guide" => "translation.md", "References" => [ "Public API" => "refs/api.md", "Internal" => "refs/internal.md", diff --git a/docs/src/refs/api.md b/docs/src/refs/api.md index 1d0fafce..01aeb64a 100644 --- a/docs/src/refs/api.md +++ b/docs/src/refs/api.md @@ -1,4 +1,4 @@ -# Public API +# [Public API](@id API) ## Index diff --git a/docs/src/translation.md b/docs/src/translation.md index 67a30364..881230dd 100644 --- a/docs/src/translation.md +++ b/docs/src/translation.md @@ -1,6 +1,10 @@ -# Translation +# Translation Guide -## Basic +This page tries to give a general overview of how to translate patterns written with the built-in tools of [Base.Threads](https://docs.julialang.org/en/v1/base/multi-threading/) using the [OhMyThreads.jl API](@ref API). + +Note that this should be seen as a rough guide and (intentionally) isn't supposed to replace a systematic introduction into the [OhMyThreads.jl API](@ref API). + +## Basics ### `@threads` From e8a6907f415218b78ee92efc11332992855d1871 Mon Sep 17 00:00:00 2001 From: Carsten Bauer Date: Fri, 2 Feb 2024 14:33:11 +0100 Subject: [PATCH 3/4] warning about mutation --- docs/src/translation.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/src/translation.md b/docs/src/translation.md index 881230dd..54a926c9 100644 --- a/docs/src/translation.md +++ b/docs/src/translation.md @@ -76,7 +76,8 @@ treduce(+, data) ## Mutation -TODO: Remark why one has to be careful here (e.g. false sharing). +!!! warning + Parallel mutation of non-local state, like writing to a shared array, can be the source of correctness errors (e.g. race conditions) and big performance issues (e.g. [false sharing](https://en.wikipedia.org/wiki/False_sharing#:~:text=False%20sharing%20is%20an%20inherent,is%20limited%20to%20RAM%20caches.)). You should carefully consider whether this is necessary or whether the use of task-local storage is the better option. ```julia # Base.Threads @@ -97,7 +98,7 @@ end ```julia # OhMyThreads: Variant 2 data = rand(10) -tmap!(data, data) do i # TODO: comment on aliasing +tmap!(data, data) do i # this kind of aliasing is fine calc(i) end ``` From 0a8455956e4f75e24620fea74ac15ed3b759ae47 Mon Sep 17 00:00:00 2001 From: Carsten Bauer Date: Fri, 2 Feb 2024 14:36:22 +0100 Subject: [PATCH 4/4] final stroke --- docs/src/translation.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/docs/src/translation.md b/docs/src/translation.md index 54a926c9..09da1c5e 100644 --- a/docs/src/translation.md +++ b/docs/src/translation.md @@ -1,8 +1,6 @@ # Translation Guide -This page tries to give a general overview of how to translate patterns written with the built-in tools of [Base.Threads](https://docs.julialang.org/en/v1/base/multi-threading/) using the [OhMyThreads.jl API](@ref API). - -Note that this should be seen as a rough guide and (intentionally) isn't supposed to replace a systematic introduction into the [OhMyThreads.jl API](@ref API). +This page tries to give a general overview of how to translate patterns written with the built-in tools of [Base.Threads](https://docs.julialang.org/en/v1/base/multi-threading/) using the [OhMyThreads.jl API](@ref API). Note that this should be seen as a rough guide and (intentionally) isn't supposed to replace a systematic introduction into OhMyThreads.jl. ## Basics