-
Notifications
You must be signed in to change notification settings - Fork 43
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
radix tree prototype for profiler #245
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Build the code using CMake
- Put everything under
modmesh
namespace - Use a header file
- Ending comment
- Put test code in Google test directory
@q40603 Please let me know what's your progress or plan |
@yungyuc |
todo
questions:
|
It's a good idea to add more tests. For printing, I'd suggest to do it in Python, so the first step is to make pybind11 wrapper. Testing string representation in Python is way easier than doing that in C++. It is a separate task. You should use another PR to do it. I will write up an issue to keep track of the followup work.
Using raw pointers is the right thing to do. Inside the tree implementation we should either use a pointer or an index that works like a raw pointer. The ordinary smart pointers (STL ones) are too heavy-weight for performance. Could you please make the following finishing touches?
Hopefully the code can be merged in a day or two. But it depends on your time. |
5c344bf
to
5d18142
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Please avoid touching unrelated files. You probably need to rebase to the latest master.
Enhance: 1. generate key for function name to do key comparison 2. move getChild logic from tree to node enhance: 1. use try_emplace to get function id enhance: 1. add operator overloading in TimedEntry for printing. 2. add template for better usability enhance: 1. add ref in comment enhance: 1. rename getFunctionId to getID for general purpose enhance: 1. change to header file 2. add testing to gtests dir radix tree prototype for profiler Enhance: 1. generate key for function name to do key comparison 2. move getChild logic from tree to node enhance: 1. use try_emplace to get function id enhance: 1. add operator overloading in TimedEntry for printing. 2. add template for better usability enhance: 1. add ref in comment enhance: 1. rename getFunctionId to getID for general purpose enhance: 1. change to header file 2. add testing to gtests dir remove int main in header file clang format add parameter dialog RParameter: support int64/double types RParameter: allow building parameters list at runtime modmesh/params.py: add license RParameter: clang-format fix modmesh/params.py: fix flake8 issue check PUI version modmesh/params.py: fix test example [hotfix] reopen brew update freeze llvm version
5d18142
to
f0a8a19
Compare
Please format and tidy the code before push. Using clang-format and clang-tidy locally will save your time. |
Ready for review,
|
Also, it just came up to me that should I handle recursive function profiling? |
Yes, we should handle recursion. And you are right that we tend to avoid recursion in HPC. To be precise, we do not like function calls in tight loop, not the recursion itself. Good (fast) recursion may be replaced to loop so that in the optimized code it does not cause runtime issue. However, as you pointed out, in the profiling mode, recursion creates crazy stack entries. As a profiling tool we need to handle recurse. It is not because the code wants to use recursion, but to be able to analyze where recursion happens so that we can eliminate it. Sometimes we tolerate the non-ideal construct for quick delivery, and the profiling tool needs to show proper information. |
it seems the code is not yet usable. is there any follow-up? @q40603 |
I found it's somehow difficult to find the hierarchical representation of a object say an object is struct Foo {
void Bar1();
Void Bar2();
}; slightly modifying the proposal output, I expect to get something like this:
I expect to get a hierarchical representation like |
@q40603 please comment. |
I already found the answer, will open a PR soon :) |
@tigercosmos Thanks for bringing this up. From you comment, it seems that you want to use the radix tree to visualize the hierarchical representation of an object? The radix tree prototype is targeted at improving the TimeRegistry so function call path could be recorded during profiling. To profile the program, a user is expected to put the macro at the function he or she is interested in, such as Euler1DCore.cpp, a macro is put at the beginning of the function. In your case, the macro that needed to be put in function Bar1 should be like this
Consider the following code.
The profiling report should be like this
|
This pull request is the next step for 190
Basic Information
The current scope-based timer enables one to simply profile the program.
One can insert a macro at target function to record the execution time and exact hit count.
The scope-based timer used a map with function name as key to record how many times a function is executed.
With such information, a profiling report could be generated.
Problem to solve
Rather than knowing how many times a single function is executed, I think people will be more interested in how many times a single call path is hit during profiling as a single function may have different callers.
Also, with call path information, I am able to generate a flame graph in the future.
To record the call path, I propose to use a radix tree to dynamically construct the call graph.
Each node acts as an function being executed, and it has:
Prototype expected output