Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update Best-Practice Guide to include guidance on reducing compile time cost #53

Open
lemonade-dm opened this issue Mar 1, 2023 · 1 comment
Assignees
Labels
documentation Improvements or additions to documentation

Comments

@lemonade-dm
Copy link
Contributor

lemonade-dm commented Mar 1, 2023

To help improve O3DE C++ build times, it is recommended to update the C++ Best Practice Guide, with options on how to best reduce compilation time going forward.

There are several ways to reduce O3DE compile going forward.
One of which is reducing the amount of non-template inline functions.
Other ways include

  • Using type erasure via function pointers or AZStd::functions that can created in functions templates, but then be later used in a non-templated function implemented in a single translation unit to reduce compilation time.
  • Using forward declarations when possible. For example including either the BehaviorContext, SerializeContext or EditContext headers in .h file can almost always be avoided with a forward declaration. The Reflect function can be implemented in cpp files
  • Use the boilerplate macros which only declare functions for opt-in to structures such as O3DE Allocators, O3DE TypeInfo and O3DE RTTI.
  • Be careful with inner classes as they cannot be forward declared without the including the header of an outer class
    • For example declaring a SerializeContext VersionConverter function as follows
      static bool VersionConverter(AZ::SerializeContext& context, AZ::SerializeContext::DataElementNode& classElement);
    requires the SerializeContext.h header to be included, as the DataElementNode inner class can't be forward declare without the class definition for the SerializeContext class.

Useful macros are

  • AZ_TYPE_INFO_SPECIALIZE_WITH_DECL - most recommended way to add TypeInfo support. This only adds two additional free functions declarations of GetO3deTypeName and GetO3deTypeId.
  • AZ_TYPE_INFO_WITH_NAME_DECL - Less recommended way to add TypeInfo support. This adds an additional 4 function declaration total.
    Two non-member friend functions of the GetO3deTypeName and GetO3deTypeId functions to the current namespace containing the class.
    Two static member functions of TYPEINFO_Name and TYPEINFO_Uuid that can be used to query the name and uuid associated with a class
  • AZ_TYPE_INFO_SPECIALIZE_WITH_IMPL - The counterpart of the AZ_TYPE_INFO_SPECIALIZE_WITH_DECL which defines the two functions GetO3deTypeName and GetO3deTypeId functions.
  • AZ_TYPE_INFO_WITH_NAME_IMPL - The counterpart of the AZ_TYPE_INFO_WITH_NAME_DECL which defines the 4 functions of GetO3deTypeName and GetO3deTypeId (non-member friend functions) as well as TYPEINFO_Name and TYPEINFO_Uuid (static member functions)
  • AZ_RTTI_NO_TYPE_INFO_DECL - Declares the 10 RTTI functions(6 virtual and 4 static member) that allows a class to opt-in to RTTI
  • AZ_RTTI_NO_TYPE_INFO_IMPL - Adds the definitions for the 10 RTTI functions. It pairs with the AZ_RTTI_NO_TYPE_INFO_DECL function.
  • AZ_CLASS_ALLOCATOR_DECL - Declares the operator new and operator delete static members of a class to allow opt-in to use the AZ Class Allocators
  • AZ_CLASS_ALLOCATOR_IMPL - Adds the definitions the operator new and operator delete static members to allow class to use the AZ Allocators for allocating it's class layout when using new and delete

Other Recommendations:
In order to iterative improve build times, the following is recommended

  1. instead using the AZ_TYPE_INFO/AZ_RTTI macro directly within the declaration of a class in a header, the AZ_TYPE_INFO_WITH_NAME_DECL and AZ_RTTI_NO_TYPE_INFO_DECL macros are used to declare the TypeInfo and RTTI functions without defining them.
    In a cpp file the AZ_TYPE_INFO_WITH_NAME_IMPL and AZ_RTTI_NO_TYPE_INFO_IMPL macros can be used to define the TypeInfo/RTTI functions only once.
  2. Avoid adding inline definitions of functions in headers and instead aggressively move function definitions to translation units(.cpp files). Non-templated inline function bodies are compiled everytime they are included and it adds ups over time
    For example the PoolAllocator code was ranked for 4-7 in template functions that took the most time to instantiate contributing about 580 seconds(8 minutes 40 seconds) of compilation time.
    Now that time can get parallelized over the number of cores building at once, but even with 8 cores this adds up to over a minute
155581 ms: AZ::Internal::PoolAllocatorHelper<AZ::PoolSchema>::RTTI_IsContainType (1117 times, avg 139 ms)
143757 ms: AZ::Internal::PoolAllocatorHelper<AZ::PoolSchema>::TYPEINFO_Uuid (1117 times, avg 128 ms)
143698 ms: AZ::Internal::PoolAllocatorHelper<AZ::PoolSchema>::RTTI_Type (1117 times, avg 128 ms)
136643 ms: AZ::Internal::AggregateTypes<AZ::PoolSchema>::Uuid<AZ::CanonicalType... (1117 times, avg 122 ms)

With the changes to move the PoolAllocator instantiations and TypeInfo functions to its cpp file, those functions now longer appear in the top 10000 templates that are instantiated.

@lemonade-dm lemonade-dm added the documentation Improvements or additions to documentation label Mar 1, 2023
@lemonade-dm lemonade-dm self-assigned this Mar 1, 2023
@AMZN-alexpete
Copy link

Notes from recent meeting:
There are possibly underlying design issue that could be addressed that are likely more effort but might address these issues:

  1. Using codegen instead of relying on templates could reduce compile times.
  2. At some point, the build in c++ RTTI might be faster and smaller than our implementations. As of most recent testing (by Alan?) the memory cost was 20% more than our implementation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation
Projects
Status: 📋 Backlog
Development

No branches or pull requests

2 participants