When code is suspiciously fast: adventures in dead code elimination
jeffq.com
jeffq.com
I especially love the way he explored how social interactions could change in a society made up of people who are really immortal computer simulations. A leader changing their apparent age during parts a speech to suit the tone, the same way someone today would shift between a large smile or stern expression based on what they're delivering. Or the couple having an argument, visibly presenting themselves as standing face-to-face, yet neither of them is able to really look at each other with their actual "viewport" (and neither of them is aware if the other is doing this).
I just might have to re-read it this weekend :) Or Axiomatic, as wyager suggests, I haven't read any of those stories yet.
You don't have to print the result within the body of code that you are timing (which would skew the result), but you must have some confidence that the benchmarking setup is sufficiently close to real-world usage conditions. This usually involves the computation now knowing how its result is going to be used.
(In a similar vein, I am also very skeptical about benchmark programs that hard-code their input, rather than read it at runtime.)
Yes, which is why the volatile qualifier exists: It makes modifying specific variables a side-effect, which then cannot be optimized away.
Yes, modifying is a form of access, but too is a read. Which means one can READ hardware register in a loop and expect it to change without compiler optimizing that out.
Please check the very definition of assert() macro.
#ifdef NDEBUG
# define assert(expr) (__ASSERT_VOID_CAST (0))
#else /* Not NDEBUG. */
# define assert(expr) \
((expr) \
? __ASSERT_VOID_CAST (0) \
: __assert_fail (__STRING(expr), __FILE__, __LINE__, __ASSERT_FUNCTION))
#endif /* NDEBUG. */
Do I really need to explain this more?Here's what the assert man page says on OS X:
The assert() macro tests the given expression and if it is false, the calling process is terminated. A
diagnostic message is written to stderr and the abort(3) function is called, effectively terminating
the program.
If expression is true, the assert() macro does nothing.
The assert() macro may be removed at compile time with the cc(1) option -DNDEBUG.
Note that the “may be removed” warning is at the end, where it's easy to miss and it mentions a specific compiler flag rather than the concept of a release build.On Linux, the man page leads with that discussion:
If the macro NDEBUG was defined at the moment <assert.h> was last included, the macro assert() generates no
code, and hence does nothing at all. Otherwise, the macro assert() prints an error message to standard error
and terminates the program by calling abort(3) if expression is false (i.e., compares equal to zero).
The purpose of this macro is to help the programmer find bugs in his program. The message "assertion failed
in file foo.c, function do_bar(), line 1287" is of no help at all to a user.
You're not wrong but you're being very optimistic to assume that a) every C programmer, including those grinding away on massive projects, has learned about this and knows every compiler flag in use and preprocessor macro defined in every file and b) large applications haven't accreted so much code in assert calls in that the current maintainers are afraid to turn it off. Stories like this one pop up every so often in the programming community for a reason."Assert" isn't necessarily limited to the macro in assert.h. Some places, including I assume Blizzard, have more control over which builds remove which asserts.
If Blizzard, et al. are using their own definition of asserts then they're responsible for their semantics. That doesn't change what is commonly understand as "assertion" in C/C++ code, and the author of this article is (apparently) using the bog-standard assert macro.
* http://www.boost.org/doc/libs/release/libs/assert/assert.htm...
* https://wiki.libsdl.org/CategoryAssertions
* https://msdn.microsoft.com/en-us/library/ew16s3zc.aspx
* https://github.com/questor/eastl/blob/master/assert.cpp
* http://kernelnewbies.org/FAQ/BUG
Plus my copy of "The C++ Programming Language" (3rd edition) includes an example of creating an assertion facility that uses exceptions. I don't know who you talk to, but when assert comes up in conversations -- even conversations limited to C or C++ -- I know what the assert is meant to do but I don't assume I know where it's defined or if it's a one-size-fits-all approach.
https://en.wikipedia.org/wiki/The_Power_of_10:_Rules_for_Dev...
safety first
I'm very amazed by the simplicity of this example. Are there more serious optimization that can be seen with simple code?
http://stackoverflow.com/questions/11227809/why-is-processin...
Have a look at the "Update" to the top answer, specifically what the intel compiler does.
I've run into this problem several times. Something like a for loop that doesn't do anything but is supposed to eat up time will easily be eliminated, making your attempts at measuring the time taken a bit meaningless.
It's probably not that Microsoft's compiler is optimizing through the function pointer, but rather that it thinks that now() doesn't have to be sequenced. And its return value is just assigned to local variables, which have no interaction with the function being called. So if now() doesn't have to be sequenced, the initializations of those variables can be reordered.
This is definitely a bug somewhere between now this now() function is implemented, and how the compiler treats its definition or declaration. A clock-sampling function simply must be properly sequenced with regard to surrounding code.
It was self-hosting, and I made it insert the funky code on compile. I also made it do precomputation on most loops.
The benchmarks at the end of the year had very un-even time distribution, and everybody knew that we had done something funny (especially since our recursive slow fibonacci was the fastest by a factor of 8).
We knew we would get caught, but it was funny anyway. Someone else won because their compiler was actually good, but we got a new special "underhanded sneakyness" prize