-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
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
aliasing in Julia #8087
Comments
I think a good fourth option is features like |
Does LLVM provide infrastructure for making optimizations that take into account that memory is not aliased? |
Yes, it has various support for alias analysis and the related metadata. @ArchRobison began using it in our codegen. We already have a lot of alias information available; for example two julia objects (except the data part of arrays) never overlap. So the situation is not quite like C, where almost anything can alias anything else. |
Interesting. Your idea to make this in a way like the |
Also worth noting that this is not just a matter for the compiler. In the case of |
Possibly awful idea... Allow dispatch on the same objects as arguments via |
Indeed. If I understand it correctly this is about optimizing "scalar" code that can use fewer instructions if certain registers don't have to be backup. In practice, efficient caching might have a much larger impact on performance. Better not talking about all that temporaries we generate on vectorized expressions... |
I am embarrassed that I just realized that my one and only Julia project so far, namely a library of containers based on balanced trees submitted for possible inclusion in DataStructures.jl, has an undocumented no-aliasing assumption in the merge!(A,B), union!(A,B) and setdiff!(A,B) routines (i.e., the routines may fail if called as merge!(A,A), union!(A,A) or setdiff!(A,A)). Obviously, I will document the no-aliasing assumption now that I realized that I had unwittingly made it. But whatever you guys decide about aliasing, I would like there to be a sentence or two about function argument aliasing in the next edition of the manual so that at least readers of the manual can start thinking about it. For example, you could create Jeff's @noaliasing macro as a no-op placeholder for now and mention in the manual that future versions of Julia will both enforce it and take advantage of it. Does setdiff!(A,B) work correctly if A==B and both are IntSets? I should look at the source code to figure this out. |
An
we could have a custom LLVM pass synthesize the LLVM noalias metadata on the loads and stores involving However, I wouldn't get wound up over noalias for optimization purposes, because the heavy hitter optimizations such as blocking matrix multiplication require more liberties to proceed:
For those reasons, I'd rather have an unordered-for loop construct, so I can clearly convey to compiler and maintainer that "I really don't care about the iteration order". (Aside: note that nested unordered loops imply stronger constraints than unordered iteration over a multidimensional space.) I'm not sure how to use such with LLVM, but maybe these high level optimizations belong at a higher level anyway. On the subject of containers, I'd prefer that the container operations handle the aliased case correctly. E.g., |
I pondered Stefan's idea. Alas it would seem to require many overloads to exclude the troublesome cases. For example, consider a
This also brings up an issue with designing a |
Perhaps it could be ok to have just two definitions, one fast with no |
Oh sorry, now I realize that we are talking about overloading. Yeah, I |
Focusing too much on |
I see now that I missed Jeff's qualification "(except the data part of arrays)". We'd need to provide a function for overlap testing and that a custom LLVM pass to exploit it. I was thinking about the pass some more and it seems that refining the TBAA information, not using |
Does Julia have a function that determines if two arrays overlap? |
Why would it have to do checking? I would think it would be useful for things like @dextorious' #21966 where you want to give the compiler the right to optimize given that you know the values will not alias. I see it as a local no aliasing scope to opt in for performance, like |
There's now techniques used in Base to address this, and other issues open for further improvements (e.g. #19658):
|
IIUC Julia doesn't have great support for aliasing safety. Nor do we have a consistent norm for how those tools should be used. I'd love to see more improvement here. IIUC Rust deals with this quite well, bu it would be very difficult for us to adopt their system. |
This is a long-term issue that has arisen out of my recent discussion with Jameson Nash on the julia users group: I would like to suggest that the core Julia developers come up with a strategy or roadmap for dealing with aliasing.
In more detail, consider a code for matrix multiplication C=A*B with the calling format matmul(A,B,C) that is implemented in the old-fashioned form of three nested loops. It is well known by now that performance boosts of huge factors-- 10 or more -- are possible by reordering the loops, blocking them, etc. Indeed, this was the whole impetus behind the LAPACK project of the 1990s. Furthermore, many papers in the compiler community explain how a compiler can automatically transform three nested loops into high-performance code.
However, if the compiler does not know that the user will never invoke the routine as matmul(A,B,A), then it cannot carry out most of these transformations because most of them would change the answer in the (unexpected) case that C and A are identical.
Currently, the Julia manual says nothing at all about aliasing among function arguments.
For this and probably other examples, it could be useful for the compiler to know that the arguments to a function will not be aliased. What is Julia's strategy in this regard? I can think of a few possibilities. As I am not a compiler person myself, I don't have a strong preference for which possibility should be followed, but I think there should be a strategy.
The text was updated successfully, but these errors were encountered: