Merge branch 'master' into jgrpp
# Conflicts: # src/core/strong_typedef_type.hpp # src/gfx.cpp # src/group_cmd.cpp # src/industry_cmd.cpp # src/map_func.h # src/newgrf_debug_gui.cpp # src/order_cmd.cpp # src/pathfinder/follow_track.hpp # src/rail_cmd.cpp # src/road_cmd.cpp # src/road_gui.cpp # src/saveload/saveload.cpp # src/screenshot.cpp # src/smallmap_gui.cpp # src/station_cmd.cpp # src/strings.cpp # src/tile_type.h # src/timetable_gui.cpp # src/town_cmd.cpp # src/train_cmd.cpp # src/viewport.cpp
This commit is contained in:
45
src/stdafx.h
45
src/stdafx.h
@@ -334,6 +334,51 @@
|
||||
#define OTTD_PRINTFHEX64 "%" OTTD_PRINTFHEX64_SUFFIX
|
||||
#define OTTD_PRINTFHEX64PAD "%016" OTTD_PRINTFHEX64_SUFFIX
|
||||
|
||||
/*
|
||||
* When making a (pure) debug build, the compiler will by default disable
|
||||
* inlining of functions. This has a detremental effect on the performance of
|
||||
* debug builds, especially when more and more trivial (wrapper) functions get
|
||||
* added to the code base.
|
||||
* Take for example the savegame called "Wentbourne", when running this game
|
||||
* for 100 ticks with the null video driver a number of fairly trivial
|
||||
* functions show up on top. The most common one is the implicit conversion
|
||||
* operator of TileIndex to unsigned int, which takes up over 5% of the total
|
||||
* run time and functionally does absolutely nothing. The remaining functions
|
||||
* for the top 5 are GB, GetTileType, Map::Size and IsTileType to a total of
|
||||
* about 12.5% of the game's total run time.
|
||||
* It is possible to still force inlining in the most commonly used compilers,
|
||||
* but that is at the cost of some problems with debugging due to the forced
|
||||
* inlining. However, the performance benefit can be enormous; when forcing
|
||||
* inlining for the previously mentioned top 5, the debug build ran about 15%
|
||||
* quicker.
|
||||
* The following debug_inline annotation may be added to functions comply
|
||||
* with the following preconditions:
|
||||
* 1: the function takes more than 0.5% of a profiled debug runtime
|
||||
* 2: the function does not modify the game state
|
||||
* 3: the function does not contain selection or iteration statements,
|
||||
* i.e. no if, switch, for, do, while, etcetera.
|
||||
* 4: the function is one line of code, excluding assertions.
|
||||
* 5: the function is defined in a header file.
|
||||
* The debug_inline annotation must be placed in front of the function, i.e.
|
||||
* before the optional static or constexpr modifier.
|
||||
*/
|
||||
#if !defined(_DEBUG) || defined(NO_DEBUG_INLINE)
|
||||
/*
|
||||
* Do not force inlining when not in debug. This way we do not work against
|
||||
* any carefully designed compiler optimizations.
|
||||
*/
|
||||
#define debug_inline inline
|
||||
#elif defined(__clang__) || defined(__GNUC__)
|
||||
#define debug_inline [[gnu::always_inline]] inline
|
||||
#else
|
||||
/*
|
||||
* MSVC explicitly disables inlining, even forced inlining, in debug builds
|
||||
* so __forceinline makes no difference compared to inline. Other unknown
|
||||
* compilers can also just fallback to a normal inline.
|
||||
*/
|
||||
#define debug_inline inline
|
||||
#endif
|
||||
|
||||
typedef unsigned char byte;
|
||||
|
||||
/* This is already defined in unix, but not in QNX Neutrino (6.x) or Cygwin. */
|
||||
|
Reference in New Issue
Block a user