【问题标题】:Using Julia to plot the mandelbrot with multithreading, race condition problem使用 Julia 绘制具有多线程、竞争条件问题的 mandelbrot
【发布时间】:2020-06-24 03:40:23
【问题描述】:

我是 Julia 的新手,我正在尝试实现 Julia 的多线程,但我相信我遇到了“竞争条件问题”。在这里,我正在绘制 mandelbrot,但我相信由于竞态条件,数组索引 [n] 会弄乱颜色映射。我尝试对索引 n 使用原子特性,但显然我不能将该类型用作索引。以下是要比较的图片以及代码块。

谢谢!

module MandelBrot
using Plots
#make some functions for mandelbrot stuff
#find out if a number is part of the set
#remember the mandelbrot is symmetrical about the real number plane

function mandel(c)
    #determine if a number is in the set or not in the set - 
    max_iter = 1000;
    bound = 2
    z = 0
    n = 0
    #if the magnitude of z exceeds two we know we are done.
    while abs(z)<bound && n<max_iter
        z = z^2+c
        n+=1
    end
    return n #if n is 1000 assume c is good, else not of the set
end

#map n to a color
function brot(n)
    rgb = 250
    m = (n%rgb) /rgb#divide 250
    if 0< n <= 250
        c = RGB(1,m,0)
    elseif 250<n<=500
        c = RGB(1-m,1,0)
    elseif 500<n<=750
        c = RGB(0,1,m)
    elseif 750<n<=999
        c = RGB(0,1-m,1)
    else
        c=RGB(0,0,0)
    end
    return c
    #TODO: append this c to an array of color values
end
#mrandom


function mandelbrot(reals,imags)
    #generate #real amount of points between -2 and 1
    #and #imag amount of points between 0 and i
    #determine if any of those combinations are in the mandelbrot set
    r = LinRange(-2,1,reals)
    i = LinRange(-1,1,imags)
    master_list = zeros(Complex{Float64},reals*imags,1)
    color_assign = Array{RGB{Float64}}(undef,reals*imags,1)
    #n = Threads.Atomic{Int64}(1)
    n = 1
        Threads.@threads for real_num in r
            for imaginary_num in i
                #z = complex(real_num, imaginary_num) #create the number
                #master_list[n] = z                      #add it to the list
                #color_assign[n,1] = (brot ∘ mandel)(z) #function of function! \circ + tab

                #or would this be faster? since we dont change z all the time?
                master_list[n] = complex(real_num, imaginary_num)
                color_assign[n,1] = (brot ∘ mandel)(complex(real_num, imaginary_num))
                n+=1
                #Threads.atomic_add!(n,1)
            end
        end
        gr(markerstrokewidth=0,markerstrokealpha=0,markersize=.5,legend=false)
        scatter(master_list,markerstrokecolor=color_assign,color=color_assign,aspect_ratio=:equal)
    end

#end statement for the module
end

julia> @time m.mandelbrot(1000,1000)
  2.260481 seconds (6.01 M allocations: 477.081 MiB, 9.56% gc time)

【问题讨论】:

    标签: multithreading julia atomic mandelbrot


    【解决方案1】:

    以下是应该有帮助的:

    function mandelbrot(reals,imags)
        r = LinRange(-2,1,reals)
        i = LinRange(0,1,imags)
        master_list = zeros(Complex{Float64},reals*imags,1)
        color_assign = Array{RGB{Float64}}(undef,reals*imags,1)
        Threads.@threads for a in 1:reals
            real_num = r[a]
            for (b, imaginary_num) in enumerate(i)
                n = (a-1)*imags + b
                master_list[n] = complex(real_num, imaginary_num)
                color_assign[n, 1] = (brot ∘ mandel)(complex(real_num, imaginary_num))
            end
        end
        gr(markerstrokewidth=0,markerstrokealpha=0,markersize=1,legend=false)
        scatter(master_list,markerstrokecolor=color_assign,color=color_assign,aspect_ratio=:equal)
    end
    

    方法是将n 计算为沿ri 的索引的函数。 另请注意,我使用1:reals 而不仅仅是enumerate(r),因为Threads.@threads 不接受任意迭代器。

    请注意,尽管您的代码可能会在其他代码中被清理,但如果没有完全可重现的示例,则很难做到这一点。

    【讨论】:

    • 谢谢卡明斯基先生!我很快就会尝试一下 - 我添加了整个代码以实现可重复性,很抱歉没有早点这样做。
    • 我刚刚检查过 - 在多个线程上一切正常。只需将其称为MandelBrot.mandelbrot(1000,1000)
    猜你喜欢
    • 2023-01-30
    • 2021-02-18
    • 2016-10-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-26
    • 1970-01-01
    相关资源
    最近更新 更多