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

Benchmarking with interpolated type gives different results #124

Closed
rfourquet opened this issue Sep 30, 2017 · 2 comments
Closed

Benchmarking with interpolated type gives different results #124

rfourquet opened this issue Sep 30, 2017 · 2 comments

Comments

@rfourquet
Copy link
Contributor

rfourquet commented Sep 30, 2017

Sorry for the unclear title. The problem can be summarized as follows: T = UInt; run(tune!(@benchmarkable rand($T))) gives a very over-estimated time compared to run(tune!(@benchmarkable rand(UInt)). While preparing a PR against julia/master, the RandomBenchmarks showed a lot of regressions because of this (in this case, T is set in a loop), even though the performance is not degraded when running individual benchmarks using the second form (i.e. using UInt directly). I tried solving this by using some incantation of eval, with no success. My last try was something like T=UInt; RD=RandomDevice(); g[...] = eval(@benchmarkable rand(Expr(:$, RD), $T) (here RD must not be interpolated by eval, only by @benchmarkable). I'm not sure whether this works as intended(edit: it doesn't), but it's ugly, so wanted to discuss this problem here before working more on this.

@jrevels jrevels changed the title Benchmarking with interpolated type is biased Benchmarking with interpolated type gives different results Oct 2, 2017
@jrevels
Copy link
Member

jrevels commented Oct 2, 2017

This behavior is intentional, but it seems to be too poorly documented in BenchmarkTools, because a lot of people run into this.

In the former example, you're asking for the runtime of a function f(UInt) where @noinline f(T) = rand(T). In the second example, you're asking for the performance of f() where @noinline f() = rand(UInt). In other words, these benchmarks are measuring different things. The question becomes: What are you interested in measuring?

For example, the former might be considerably slower due to the compiler's choice of type argument specialization, i.e. Datatype vs. Type{T} (that may or may not be what's going on in your case).

@rfourquet
Copy link
Contributor Author

Thanks for your answer. I understand the problem now, but was not aware of it when writing the random benchmarks. I had intended to measure the the second form (f() = rand(UInt)), which correspond to the performance which can be obtained by careful coding (i.e. using e.g. f(::Type{T}) instead of f(T::DataType)). I think I have got a workaround to the difficulty I mentioned (of writing @eval around @benchmarkable with $) using a simple wrapper function. I will submit a PR soon for that.

rfourquet added a commit to rfourquet/BaseBenchmarks.jl that referenced this issue Oct 8, 2017
This fixes part of JuliaCI#124. E.g. When wanting to benchmark
`rand(Int)` and `rand(UInt)`, the following loop won't
measure what is expected:
`for T=(Int, UInt); @benchmarkable rand($T); end`
In order to benchmark the equivalent of
`@benchmarkable rand(Int); @benchmarkable rand(UInt)`,
we "value-fy" the types with `Val`.
rfourquet added a commit to rfourquet/BaseBenchmarks.jl that referenced this issue Oct 8, 2017
This fixes part of JuliaCI#124. E.g. When wanting to benchmark
`rand(Int)` and `rand(UInt)`, the following loop won't
measure what is expected:
`for T=(Int, UInt); @benchmarkable rand($T); end`
In order to benchmark the equivalent of
`@benchmarkable rand(Int); @benchmarkable rand(UInt)`,
we "value-fy" the types with `Val`.
rfourquet added a commit to rfourquet/BaseBenchmarks.jl that referenced this issue Oct 8, 2017
This fixes part of JuliaCI#124. E.g. When wanting to benchmark
`rand(Int)` and `rand(UInt)`, the following loop won't
measure what is expected:
`for T=(Int, UInt); @benchmarkable rand($T); end`
In order to benchmark the equivalent of
`@benchmarkable rand(Int); @benchmarkable rand(UInt)`,
we "value-fy" the types with `Val`.
@jrevels jrevels closed this as completed Nov 17, 2017
rfourquet added a commit to rfourquet/BaseBenchmarks.jl that referenced this issue Nov 18, 2017
This fixes part of JuliaCI#124. E.g. When wanting to benchmark
`rand(Int)` and `rand(UInt)`, the following loop won't
measure what is expected:
`for T=(Int, UInt); @benchmarkable rand($T); end`
In order to benchmark the equivalent of
`@benchmarkable rand(Int); @benchmarkable rand(UInt)`,
we "value-fy" the types with `Val`.
rfourquet added a commit to rfourquet/BaseBenchmarks.jl that referenced this issue Nov 18, 2017
This fixes part of JuliaCI#124. E.g. When wanting to benchmark
`rand(Int)` and `rand(UInt)`, the following loop won't
measure what is expected:
`for T=(Int, UInt); @benchmarkable rand($T); end`
In order to benchmark the equivalent of
`@benchmarkable rand(Int); @benchmarkable rand(UInt)`,
we "value-fy" the types with `Val`.
jrevels pushed a commit that referenced this issue Nov 20, 2017
This fixes part of #124. E.g. When wanting to benchmark
`rand(Int)` and `rand(UInt)`, the following loop won't
measure what is expected:
`for T=(Int, UInt); @benchmarkable rand($T); end`
In order to benchmark the equivalent of
`@benchmarkable rand(Int); @benchmarkable rand(UInt)`,
we "value-fy" the types with `Val`.
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

2 participants