AMREX_ENUM: Cache String Map#4643
Conversation
The `getEnumNameValuePairs` logic used below a lot of `AMREX_ENUM` functions is very slow for long-enough (e.g., N>70) enums. In WarpX 1D simulations, it took up close to 50% of the runtime, as Dave Grote found. This caches the key-value string list on first creation, because the type is known at compile-time. A better implementation might skip the dictionary altogether for functions that just need one string, like `getEnumNameString`.
|
I think we should create a helper function to avoid multiple statics. Something like |
|
Can we even create an optimized version of |
|
Depending the size, maybe using std::map or std::unordered_map is better than std::vector. But it's hard to avoid building the whole list. |
|
@WeiqunZhang ready from my end @dpgrote can you please test if this solves your performance issue on WarpX 1D runs? :) |
|
We could also test alternative versions using std::map or std::unordered_map. |
|
This seems to work, thanks! I did a test comparing the time spent in the |
|
Probably because the WarpX PR uses std::map. |
|
|
||
| template <typename T, typename ET = amrex_enum_traits<T>, | ||
| std::enable_if_t<ET::value,int> = 0> | ||
| std::vector<std::pair<std::string,T>> getEnumNameValuePairs () |
There was a problem hiding this comment.
We should return by const&.
There was a problem hiding this comment.
Oh, we never resolved this comment. I believe we should return by const& for performance.
Summary
The
getEnumNameValuePairslogic used below a lot ofAMREX_ENUMfunctions is very slow for long-enough (e.g., N>70) enums.In WarpX 1D simulations, it took up close to 50% of the runtime, as Dave Grote found.
This caches the key-value string list on first creation, because the type is known at compile-time.
A better implementation might skip the dictionary altogether for functions that just need one string, like
getEnumNameString.Additional background
BLAST-WarpX/warpx#6139
Checklist
The proposed changes: