Closed nemequ closed 4 years ago
I took a closer look at this, and I think I spoke too soon about it being easy :(. Luckily they support __builtin_expect
, so adding Cray to that list is trivial. 4f8bb0fead29a4e6afd8a7fb0c8d658375bb4d11 does that… copying the commit message which has a lot more information:
Cray also has a probability pragma, but I'm not sure how to make it work here. Unlike __builtin_expect
, the pragma goes inside the condition, so instead of
if (__builtin_expect_with_probability(x, 1, 0.9)) {
do_stuff();
}
Cray wants
if (x) {
#pragma probability 0.9
do_stuff();
}
To be honest, I think I prefer Cray's version. It's really nice for the common case (if blocks), though it does have some disadvantages… for one thing, putting it in a pragma means it's a bit of a pain to write a macro where one of the parameters is the probability since you have to go through a secondary macro like HEDLEY_STRINGIFY
(e.g., _Pragma(HEDLEY_STRINGIFY(probability N))
). It's also a bit ugly to use inside of statements, like when using __builtin_expect_with_probability
in a ternary operator.
The biggest disadvantage, though, is that I can't see a good way to make Cray's version act more like __builtin_expect_with_probability
so we can have one macro that works everywhere. The best I can think of is
# define HEDLEY_PREDICT(expr, expected, prob) \
(__extension__ ({ \
const __typeof__(expr) hedley_expr_ = (expr); \
if (hedley_expr_ == (expected)) { \
_Pragma(HEDLEY_STRINGIFY(probability prob)) \
} \
hedley_expr_; \
}))
# define HEDLEY_PREDICT_TRUE(expr, prob) \
(__extension__ ({ \
const __typeof__(expr) hedley_expr_ = (expr); \
if (!!hedley_expr_) { \
_Pragma(HEDLEY_STRINGIFY(probability prob)) \
} \
hedley_expr_; \
}))
# define HEDLEY_PREDICT_FALSE(expr, prob) \
(__extension__ ({ \
const __typeof__(expr) hedley_expr_ = (expr); \
if (!hedley_expr_) { \
_Pragma(HEDLEY_STRINGIFY(probability prob)) \
} \
hedley_expr_; \
}))
So for
if (HEDLEY_PREDICT(x, 1, 0.9)) {
do_stuff();
}
you end up with something that looks vaguely like
if ((__extension__ ({
const __typeof__(x) hedley_expr_ = (x);
if (hedley_expr_ == 1) {
#pragma probability 0.9
}
hedley_expr_;
}))) {
do_stuff();
}
Which it feels like Cray may be able to optimize, but without access to the compiler I can't be sure so it's probably safer to just rely on __builtin_expect
, which we know Cray will be able to take advantage of.
I was looking at the Cray manual, and noticed that Cray supports
__builtin_expect
as well as a probability pragma which could be used to implementHEDLEY_PREDICT
.Shouldn't be hard, I'm just in the middle of something else right now and don't want to forget to come back and write the implementation.