PCSX2 Documentation/Code Formatting Guidelines: Difference between revisions

Line 54: Line 54:
==Topic Ex: Specifying Function Inlining==
==Topic Ex: Specifying Function Inlining==


'''''IMPORTANT''''' '''This section is preliminary documentation for a planned design, and is not currently implemented in the PCSX2 sourcecode.'''
'''''IMPORTANT!''''' '''This section is preliminary documentation for a planned design, and is not currently implemented in the PCSX2 sourcecode.'''


While modern compilers like to tout that the compiler should be left to decide function inlining, the truth is that for PCSX2's purposes compiler inlining heuristics fail miserably, never inlining nearly as much as they should. It's often necessary for us as programmers to tell the compiler what to inline. PCSX2 offers four special classes of forced function inlining, which are provided as replacements for `__forceinline,` `inline,` and `__attribute__(always_inline)`. When used properly, these inlining attributes help improve the performance and quality of devel and debug builds.
While modern compilers like to tout that the compiler should be left to decide function inlining, the truth is that for PCSX2's purposes compiler inlining heuristics fail miserably, never inlining nearly as much as they should. It's often necessary for us as programmers to tell the compiler what to inline. PCSX2 offers four special classes of forced function inlining, which are provided as replacements for <code>__forceinline,</code> <code>inline,</code> and <code>__attribute__(always_inline)</code>. When used properly, these inlining attributes help improve the performance and quality of devel and debug builds.


**`inline_always`** this attribute force inlines a function even in debug builds. It is the functional equivalent of C#'s "skipover" attribute, and should generally be applied only to very simple accessor operations. It acts as both a speedup of debug build performance and as a convenience tool, allowing debuggers to trace through code without having to manually trace into every basic object constructor or property accessor.
'''<code>inline_always</code>''' this attribute force inlines a function even in debug builds. It is the functional equivalent of C#'s "skipover" attribute, and should generally be applied only to very simple accessor operations. It acts as both a speedup of debug build performance and as a convenience tool, allowing debuggers to trace through code without having to manually trace into every basic object constructor or property accessor.


**`inline_devel`** this attribute enables inlining in both devel and release builds, and should be used on almost any function for which the programmer knows that inlining is in the best interest of the code performance. Keep in mind, however, that devel builds are used as debugging and stack tracing tools by programmers and testers, and that means some types of functions are not well suited to being inlined. These namely include very long/complicated functions, which should bear the `inline_release` attribute instead.
'''<code>inline_devel</code>''' this attribute enables inlining in both devel and release builds, and should be used on almost any function for which the programmer knows that inlining is in the best interest of the code performance. Keep in mind, however, that devel builds are used as debugging and stack tracing tools by programmers and testers, and that means some types of functions are not well suited to being inlined. These namely include very long/complicated functions, which should bear the `inline_release` attribute instead.


**`inline_release`** this attribute enables inlining in public release builds only. This attribute should generally be used on functions that are very long and involved, and only called from one to three locations, thus making them good candidiates for inlining (these are cases the compiler's optimizer should be smart enough to inline itself in release builds, but generally fails to inline).
'''<code>inline_release</code>''' this attribute enables inlining in public release builds only. This attribute should generally be used on functions that are very long and involved, and only called from one to three locations, thus making them good candidiates for inlining (these are cases the compiler's optimizer should be smart enough to inline itself in release builds, but generally fails to inline).


**`inline_never`** special attribute which force-disables inlining of a function completely. This attribute is of extremely limited use, usually to combat stupid inlining tricks that some compilers might fall into on special cases of complex function nesting, so you probably won't even need to remember it exists unless you make a habit of writing complex and hard to understand class implementations.
'''<code>inline_never</code>''' special attribute which force-disables inlining of a function completely. This attribute is of extremely limited use, usually to combat stupid inlining tricks that some compilers might fall into on special cases of complex function nesting, so you probably won't even need to remember it exists unless you make a habit of writing complex and hard to understand class implementations.


===Topic Ex.2: Savestate Versioning===
===Topic Ex.2: Savestate Versioning===


While PCSX2 willfully makes no promise to retain backwards support for savestates, it is none the less a convenience for developer, tester, and user alike when we do. So when possible it is recommended that programmers making changes to the savestate code (normally denoted as a Freeze() function) be sure to increment the savestate version in Savestate.h and, if you know how, implement backward support for the old version (if not, then simply increment the savestate version and let someone else fix the backwards compatibility in a later revision). This allows PCSX2 to at the very least fail gracefully when encountering an unknown savestate, and ideally it allows for another coder familiar with the system to properly implement backwards compatibility with the older savestate revision.
While PCSX2 willfully makes no promise to retain backwards support for savestates, it is none the less a convenience for developer, tester, and user alike when we do. So when possible it is recommended that programmers making changes to the savestate code (normally denoted as a Freeze() function) be sure to increment the savestate version in Savestate.h and, if you know how, implement backward support for the old version (if not, then simply increment the savestate version and let someone else fix the backwards compatibility in a later revision). This allows PCSX2 to at the very least fail gracefully when encountering an unknown savestate, and ideally it allows for another coder familiar with the system to properly implement backwards compatibility with the older savestate revision.
ninja
782

edits