-
-
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
Better documentation for performance annotations #17700
Changes from 2 commits
3b4bf9e
0b5d1b2
3bb9597
b14c3cd
96d2ef9
35d0c08
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -888,11 +888,6 @@ properties. | |
**This feature is experimental** and could change or disappear in future | ||
versions of Julia. | ||
|
||
Note: While :obj:`@simd` needs to be placed directly in front of a | ||
loop, both :obj:`@inbounds` and :obj:`@fastmath` can be applied to | ||
several statements at once, e.g. using ``begin`` ... ``end``, or even | ||
to a whole function. | ||
|
||
Here is an example with both :obj:`@inbounds` and :obj:`@simd` markup:: | ||
|
||
function inner( x, y ) | ||
|
@@ -932,6 +927,13 @@ On a computer with a 2.4GHz Intel Core i5 processor, this produces:: | |
GFlop = 1.9467069505224963 | ||
GFlop (SIMD) = 17.578554163920018 | ||
|
||
Certain preconditions need to be met before using some of these macros. | ||
Both :obj:`@simd` and :obj:`@inbounds` do a simple rewrite of the expression | ||
and delegate the optimizations to compiler, much like ``:meta`` expressions. | ||
This means they merely give the compiler license to optimize. Whether | ||
it actually does so depends on the compiler. As consequence how you | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. "As consequence" is not grammatical. Actually, I think you can just delete the "As consequence..." sentence. |
||
write the expressions will have a final say on the output. | ||
|
||
The range for a ``@simd for`` loop should be a one-dimensional range. | ||
A variable used for accumulating, such as ``s`` in the example, is called | ||
a *reduction variable*. By using :obj:`@simd`, you are asserting several | ||
|
@@ -946,10 +948,8 @@ properties of the loop: | |
A loop containing ``break``, ``continue``, or :obj:`@goto` will cause a | ||
compile-time error. | ||
|
||
Using :obj:`@simd` merely gives the compiler license to vectorize. Whether | ||
it actually does so depends on the compiler. To actually benefit from the | ||
current implementation, your loop should have the following additional | ||
properties: | ||
To actually benefit from :obj:`@simd` current implementation, your loop | ||
should have the following additional properties: | ||
|
||
- The loop must be an innermost loop. | ||
- The loop body must be straight-line code. This is why :obj:`@inbounds` is | ||
|
@@ -962,7 +962,55 @@ properties: | |
- The stride should be unit stride. | ||
- In some simple cases, for example with 2-3 arrays accessed in a loop, the | ||
LLVM auto-vectorization may kick in automatically, leading to no further | ||
speedup with :obj:`@simd`. | ||
speedup with :obj:`@simd``. | ||
|
||
While :obj:`@simd` needs to be placed in front of a loop, that is not the case | ||
for :obj:`@inbounds`. It can be placed in front of any expression as long as it | ||
is inside a function, the only place where it could be outside of a function | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Semicolon, not comma, before "the only place where it can be" (not "could") |
||
definition is in front of a loop. | ||
|
||
julia> x = [1] | ||
|
||
julia> @inbounds if true | ||
x[2] | ||
end | ||
ERROR: BoundsError: attempt to access 1-element Array{Int64,1} at index [2] | ||
in getindex(::Array{Int64,1}, ::Int64) at ./array.jl:309 | ||
in eval(::Module, ::Any) at ./boot.jl:225 | ||
in macro expansion at ./REPL.jl:92 [inlined] | ||
in (::Base.REPL.##1#2{Base.REPL.REPLBackend})() at ./event.jl:46 | ||
|
||
julia> function f(x) | ||
@inbounds if true | ||
x[2] | ||
end | ||
end | ||
|
||
julia> f(x) | ||
|
||
julia> @inbounds for i in 1:10 | ||
x[2] | ||
end | ||
|
||
Beware using it before a function declaration will have no effect, the | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Beware -> Be aware that. Start a new sentence, and rephrase "To use |
||
correct way to encapsule a function or block of code is inside a | ||
``begin`` ``end`` statement. | ||
|
||
julia> @inbounds function g(x) #Won't remove bound checks nor warn you | ||
for i in 1:10 | ||
x[i] = x[i]^2 | ||
end | ||
end | ||
|
||
julia> function g(x) | ||
@inbounds begin | ||
for i in 1:10 | ||
x[i] = x[i]^2 | ||
end | ||
end | ||
end | ||
|
||
:obj:`@simd` can be placed in front of any expression without problems. | ||
|
||
Here is an example with all three kinds of markup. This program first | ||
calculates the finite difference of a one-dimensional array, and then | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
delegate the optimizations to the compiler