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

@noopt macro for avoiding optimizations #29817

Closed
KristofferC opened this issue Oct 26, 2018 · 7 comments
Closed

@noopt macro for avoiding optimizations #29817

KristofferC opened this issue Oct 26, 2018 · 7 comments
Labels
performance Must go faster

Comments

@KristofferC
Copy link
Member

KristofferC commented Oct 26, 2018

For e.g. benchmarking purposes it would be convenient to have a @noopt macro or something that would instruct the compiler not to optimize something. For example, the google benchmark suite has the following code

// The DoNotOptimize(...) function can be used to prevent a value or
// expression from being optimized away by the compiler. This function is
// intended to add little to no overhead.
// See: https://youtu.be/nXaxk27zwlk?t=2441
#ifndef BENCHMARK_HAS_NO_INLINE_ASSEMBLY
template <class Tp>
inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp const& value) {
  asm volatile("" : : "r,m"(value) : "memory");
}

https://github.com/google/benchmark/blob/d8c0f27448dfad95b94285e612bba1f7c55c9dd0/include/benchmark/benchmark.h#L304-L347

(also see https://www.youtube.com/watch?v=nXaxk27zwlk&feature=youtu.be&t=2441 as the comment links to)

It would be useful to have something similar in Julia.

@KristofferC KristofferC added the performance Must go faster label Oct 26, 2018
@KristofferC KristofferC changed the title @noopt macro @noopt macro for avoiding optimizations Oct 26, 2018
@yuyichao
Copy link
Contributor

@noinline?

@KristofferC
Copy link
Member Author

KristofferC commented Oct 26, 2018

Is that really enough?

julia> @noinline f(x) = sin(x)*exp(x)
f (generic function with 1 method)

julia> g() = (x = 2.0; for i in 1:10^5; f(x); end)
g (generic function with 2 methods)

julia> @time g()
  0.000004 seconds (4 allocations: 160 bytes)

I want the compiler to assume that f (or just reading x) has an arbitrary side effect so it better actually run the code in there.

@vchuravy
Copy link
Member

My favourite line is:

  │         (Main.f)(x::Const(2.0, false))::Const(6.71885, false)                                                                                                                               │

But there are two separate concerns here.
The first is that the Julia optimizer is becoming scarily clever (when did we start constant-propping through exp and sin...),
The second one is that you want clobber and escape from JuliaCI/BenchmarkTools.jl#92 if you don't want LLVM to pull the rug out under your feet.

@JeffreySarnoff
Copy link
Contributor

We do need @noopt in addition to @noinline unless @noinline is going to do things in addition to precluding the inlining of some code (it seems that it does some of that already .. not sure). Anyway it would be best for @noinline to suppress inlining and @noopt to have at least two flavors. For benchmarking, we want @noopt to let the code we have written be instrumented and analyzed without introducing possibly helpful transformations that take the process away from our focus.

The other flavor, or another modifier [what which one is theoretically best] that captures the notion of "Please do what you can to take this stellar code to the next level of stellar without monkeying about with this line/ these few lines / this little section; that's the only way to preserve the design semantics."

@KristofferC
Copy link
Member Author

Should probably be put inside a benchmarking package.

@JeffreySarnoff
Copy link
Contributor

I had wanted this for general use with writing parts of numerical code that must not be reorganized or optimized away by the compiler. It would be problematic to have to depend upon a benchmarking package for this.

@KristofferC
Copy link
Member Author

I had wanted this for general use with writing parts of numerical code that must not be reorganized or optimized away by the compiler.

Could you give an example? An optimization is not supposed to be observable.

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

No branches or pull requests

4 participants