JuliaGeometry / Meshes.jl

Computational geometry and meshing algorithms in Julia
https://juliageometry.github.io/MeshesDocs/stable
Other
376 stars 80 forks source link

Attempt to use threads in sideof #919

Closed juliohm closed 2 weeks ago

juliohm commented 2 weeks ago

Appreciate if someone can suggest the necessary fixes to make it work properly. The premature return and continue statements are causing problems I suppose.

eliascarv commented 2 weeks ago

The code has been adjusted and is now working.

codecov[bot] commented 2 weeks ago

Codecov Report

All modified and coverable lines are covered by tests :white_check_mark:

Project coverage is 89.00%. Comparing base (1f2e26d) to head (0c1ba67).

Additional details and impacted files ```diff @@ Coverage Diff @@ ## master #919 +/- ## ========================================== - Coverage 89.01% 89.00% -0.02% ========================================== Files 176 176 Lines 5380 5382 +2 ========================================== + Hits 4789 4790 +1 - Misses 591 592 +1 ```

:umbrella: View full report in Codecov by Sentry.
:loudspeaker: Have feedback on the report? Share it here.

eliascarv commented 2 weeks ago

Benchmarks

Benchmark 1

using Meshes, GeoArtifacts, BenchmarkTools

r = GADM.get("BRA").geometry[1] |> parent |> first |> rings |> first
p1 = Point(-50, -10)
p2 = first(vertices(r))
p3 = center(first(segments(r)))
p4 = Point(-70, -30)

@btime sideof($p1, $r)
@btime sideof($p2, $r)
@btime sideof($p3, $r)
@btime sideof($p4, $r)

Benchmark 2

using Meshes, GeoArtifacts

r = GADM.get("BRA").geometry[1] |> parent |> first |> rings |> first
b = boundingbox(r)
g = CartesianGrid(minimum(b), maximum(b), dims=(200,200))
ps = (centroid(g, i) for i in 1:nelements(g))

@time sideof(ps, r)

Results

master

julia> @btime sideof($p1, $r)
  1.401 ms (0 allocations: 0 bytes)
IN::SideType = 0

julia> @btime sideof($p2, $r)
  8.407 ns (0 allocations: 0 bytes)
ON::SideType = 2

julia> @btime sideof($p3, $r)
  8.606 ns (0 allocations: 0 bytes)
ON::SideType = 2

julia> @btime sideof($p4, $r)
  1.454 ms (0 allocations: 0 bytes)
OUT::SideType = 1
julia> @time sideof(ps, r)
 57.879324 seconds (358.79 k allocations: 15.685 MiB)
40000-element Vector{SideType}:
 OUT::SideType = 1
 OUT::SideType = 1
 OUT::SideType = 1
 ⋮
 OUT::SideType = 1
 OUT::SideType = 1

PR (8 threads)

julia> @btime sideof($p1, $r)
  547.110 μs (43 allocations: 4.52 KiB)
IN::SideType = 0

julia> @btime sideof($p2, $r)
  3.615 μs (43 allocations: 4.52 KiB)
ON::SideType = 2

julia> @btime sideof($p3, $r)
  3.932 μs (43 allocations: 4.52 KiB)
ON::SideType = 2

julia> @btime sideof($p4, $r)
  523.561 μs (43 allocations: 4.52 KiB)
OUT::SideType = 1
julia> @time sideof(ps, r)
 24.436554 seconds (5.72 M allocations: 441.366 MiB, 0.31% gc time, 12.15% compilation time)
40000-element Vector{SideType}:
 OUT::SideType = 1
 OUT::SideType = 1
 OUT::SideType = 1
 ⋮
 OUT::SideType = 1
 OUT::SideType = 1

Version info

Julia Version 1.10.4
Commit 48d4fd48430 (2024-06-04 10:41 UTC)
Build Info:
  Official https://julialang.org/ release
Platform Info:
  OS: Linux (x86_64-linux-gnu)
  CPU: 12 × Intel(R) Core(TM) i5-10400 CPU @ 2.90GHz
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-15.0.7 (ORCJIT, skylake)
Threads: 8 default, 0 interactive, 4 GC (on 12 virtual cores)
juliohm commented 2 weeks ago

The benchmark results indicate that the multi-threaded implementation is always faster when the point is IN or OUT the ring, which is by far the most common case. The slow-down in the ON case will rarely occur in practice.

We just need to make sure that the results match, i.e., the multi-threaded implementation is correct. After that, we can merge the PR and release a patch.

juliohm commented 2 weeks ago

The results match. Merging it.