From be60435ff726fa2528e2857d9003e09e53596d86 Mon Sep 17 00:00:00 2001 From: Elizabeth Smith Date: Tue, 6 May 2014 17:41:09 -0700 Subject: [PATCH] Benchmark specific fixes Summary: benchmark is necessary to get the tests running primarily replacing a few inline asm items with MSVC intrinsics and do not optimize tricks also a fix for use of the gcc specific ## with __VAR_ARGS__ although that is primarily intended as a workaround for trailing commas, gcc apparently cuts off all items in the macro afterwards this was being used for a clever/dirty trick to do one or none for a macro replaced instead with a version that will work for all other compilers (might need to be expanded for more args, but for now it's working with all current usage) @override-unit-failures also fixed a use of max without specifying a template type that was making msvc barf - specifying it (as in the min case) made it compile cleanly Test Plan: fbconfig -r folly && fbmake runtests Reviewed By: andrei.alexandrescu@fb.com FB internal diff: D1313609 --- folly/Benchmark.cpp | 6 +++++- folly/Benchmark.h | 13 +++++++++++++ folly/Preprocessor.h | 16 ++++++++++++++++ 3 files changed, 34 insertions(+), 1 deletion(-) diff --git a/folly/Benchmark.cpp b/folly/Benchmark.cpp index 7de05691..dc08f506 100644 --- a/folly/Benchmark.cpp +++ b/folly/Benchmark.cpp @@ -56,7 +56,11 @@ static vector> benchmarks; // Add the global baseline BENCHMARK(globalBenchmarkBaseline) { +#ifdef _MSC_VER + _ReadWriteBarrier(); +#else asm volatile(""); +#endif } void detail::addBenchmarkImpl(const char* file, const char* name, @@ -210,7 +214,7 @@ static double runBenchmarkGetNSPerIteration(const BenchmarkFun& fun, // the clock resolution is worse than that, it will be larger. In // essence we're aiming at making the quantization noise 0.01%. static const auto minNanoseconds = - max(FLAGS_bm_min_usec * 1000UL, + max(FLAGS_bm_min_usec * 1000UL, min(resolutionInNs * 100000, 1000000000ULL)); // We do measurements in several epochs and take the minimum, to diff --git a/folly/Benchmark.h b/folly/Benchmark.h index 19806028..3465fa1c 100644 --- a/folly/Benchmark.h +++ b/folly/Benchmark.h @@ -230,10 +230,23 @@ addBenchmark(const char* file, const char* name, Lambda&& lambda) { * good job at eliminating unused variables, and this function fools * it into thinking var is in fact needed. */ +#ifdef _MSC_VER + +#pragma optimize("", off) + +template +void doNotOptimizeAway(T&& datum) { + datum = datum; +} + +#pragma optimize("", on) + +#else template void doNotOptimizeAway(T&& datum) { asm volatile("" : "+r" (datum)); } +#endif } // namespace folly diff --git a/folly/Preprocessor.h b/folly/Preprocessor.h index c7e580d8..9f39ac58 100644 --- a/folly/Preprocessor.h +++ b/folly/Preprocessor.h @@ -28,8 +28,24 @@ * FB_ONE_OR_NONE(hello) expands to nothing. This macro is used to * insert or eliminate text based on the presence of another argument. */ +#ifdef _MSC_VER + +#define VA_NARGS_IMPL(_1, _2, _3, _4, _5, N, ...) N +#define VA_NARGS(...) VA_NARGS_IMPL(X,##__VA_ARGS__, 4, 3, 2, 1, 0) +#define VARARG_IMPL2(base, count, ...) base##count(__VA_ARGS__) +#define VARARG_IMPL(base, count, ...) VARARG_IMPL2(base, count, __VA_ARGS__) +#define VARARG(base, ...) VARARG_IMPL(base, VA_NARGS(__VA_ARGS__), __VA_ARGS__) + +#define FB_ONE_OR_NONE0() /* */ +#define FB_ONE_OR_NONE1(x) /* */ +#define FB_ONE_OR_NONE2(x, y) x +#define FB_ONE_OR_NONE3(x, y, z) x +#define FB_ONE_OR_NONE(...) VARARG(FB_ONE_OR_NONE, __VA_ARGS__) + +#else #define FB_ONE_OR_NONE(a, ...) FB_THIRD(a, ## __VA_ARGS__, a) #define FB_THIRD(a, b, ...) __VA_ARGS__ +#endif /** * Helper macro that extracts the first argument out of a list of any -- 2.34.1