Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tmap and thread-local variables #132

Open
alfaromartino opened this issue Dec 4, 2024 · 0 comments
Open

tmap and thread-local variables #132

alfaromartino opened this issue Dec 4, 2024 · 0 comments

Comments

@alfaromartino
Copy link

Sorry to bother you again, it's just that I'm writing a sectino on multithreading and I'm still exploring this package.

I was surprised that tmap doesn't automatically define thread-local variables inside anonymous functions.

# `temp` is not thread-local, wronly returns [2,2]
function  = zeros(Int, 2)
    temp = 0

    tmap(1:2) do i
        temp   = i; sleep(i/2)
        out[i] = temp
    end

    return out
end
println(foo())

For reference, LoopVectorization automatically creates a thread-local variable when vmapntt is used (the parallel version of vmapnt)

# `temp` is thread-local, it correctly returns [1,2]
function  = zeros(Int, 2)
    temp = 0

    vmapntt(1:2) do i
        temp   = i; sleep(i/2)
        out[i] = temp
    end

    return out
end
println(foo())

Given that the package aims to be simple and user-friendly, maybe this behavior is undesirable?
I took the package as for people that want to apply multithreading, without being aware of the subtleties of multithreading.

If there are reasons for this choice, I think there should be a big warning in each function documentation.
I was wrongly taking for granted that this was internally handled, considering that false sharing issues were handled and that LoopVectorization also deals with it.
I'm even more concerned about people not aware of these subtle issues, as it'd directly create a correctness issues. I can imagine that they'd think that the above implementation of tmap is the same as the following.

# `temp` is thread-local, it correctly returns [1,2]
function compute(i, out)
    temp   = i; sleep(i/2)
    out[i] = temp
end

function foo()
    out  = zeros(Int, 2)
    temp = 0

    tmap(i -> compute(i, out), 1:2) 
        
    return out
end
println(foo())

Just in case, I assumed the possibility that tforeach wasn't necessarily defining thread-local variables, as it was presented as an alternative implementation to for-loops. However it wasn't the same intuition that I had for tmap. Not saying that this is a general problem, but that maybe others will also have the same wrong impression.

Thanks again for all your efforts!!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant