Benchmark specific fixes
authorElizabeth Smith <elizabeths@fb.com>
Wed, 7 May 2014 00:41:09 +0000 (17:41 -0700)
committerDave Watson <davejwatson@fb.com>
Tue, 20 May 2014 19:53:57 +0000 (12:53 -0700)
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
folly/Benchmark.h
folly/Preprocessor.h

index 7de0569148c5b6aa9c015401674c96c49597d17f..dc08f50661dcc630909a4c376f22211d45fb6873 100644 (file)
@@ -56,7 +56,11 @@ static vector<tuple<const char*, const char*, BenchmarkFun>> 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<uint64_t>(FLAGS_bm_min_usec * 1000UL,
         min<uint64_t>(resolutionInNs * 100000, 1000000000ULL));
 
   // We do measurements in several epochs and take the minimum, to
index 19806028a96242a2cd45cf288fdadaabbacb9633..3465fa1c07ff7c4e33c7ea9d5340cdee7c31a751 100644 (file)
@@ -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 <class T>
+void doNotOptimizeAway(T&& datum) {
+  datum = datum;
+}
+
+#pragma optimize("", on)
+
+#else
 template <class T>
 void doNotOptimizeAway(T&& datum) {
   asm volatile("" : "+r" (datum));
 }
+#endif
 
 } // namespace folly
 
index c7e580d81d4d947405caec69ce8c95f833d9b027..9f39ac584561fd3120d178ea19086b746505afba 100644 (file)
  * 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