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

Support for sample filtering by thread #86

Merged
merged 9 commits into from
Aug 21, 2021
Merged

Support for sample filtering by thread #86

merged 9 commits into from
Aug 21, 2021

Conversation

aaalexandrov
Copy link
Contributor

Implement source thread-aware sample gathering, file format and display in the UI.
Add sample filtering by thread.
Add symbol per-thread statistics UI.
Fixes #70

@CyberShadow
Copy link
Member

I can't open old .sleepy files with this change, could you please check?
We should support loading old files even when the format for new files changes.

@aaalexandrov
Copy link
Contributor Author

I did not add compatibility code for opening the old file format files because I saw no compatibility code there for any old versions.
There didn't seem to be any infrastructure for that in place, aside from comparing to the current version and aborting in case it's different.
I can add loading from 0.90 specifically, but not backwards from there.
Out of curiosity, how often does this format change?

@CyberShadow
Copy link
Member

I did not add compatibility code for opening the old file format files because I saw no compatibility code there for any old versions.

You're right, my mistake. I thought I remembered some compatibility code, but I guess I was wrong. So, I take that back (though of course, speaking of a separate enhancement, compatibility would be nice if possible).

Out of curiosity, how often does this format change?

Well, the 0.90 version was bumped in 2014...

@aaalexandrov
Copy link
Contributor Author

I'll do compatibility from 0.90 in the coming days, it should be straightforward enough.

@CyberShadow
Copy link
Member

OK, only if you want (my initial statement was based on a bad assumption, and practically speaking, it's easy enough to download an older version to open older files).

Since you're working with threads, maybe looking at #4 would be a better use of your time.

As for this PR, I will try to have a closer look at it and merge it soon.

@aaalexandrov
Copy link
Contributor Author

I'll see what I can do about sampling newly spawned threads.
Is there a better way to detect them than just polling and comparing to the threads we're already tracking?

@CyberShadow
Copy link
Member

I believe that a long time ago, @rmitton tried to implement this by making Very Sleepy also work as a debugger, attaching itself to the process. That would allow it to be notified of new threads using CREATE_PROCESS_DEBUG_EVENT.

There is code for this in src/profiler/debugger.cpp, but it was never finished.

See also #20.

Copy link
Member

@CyberShadow CyberShadow left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here are my observations so far. I am going to try and see if this results in any changes in performance in practice.

src/appinfo.h Outdated Show resolved Hide resolved
src/profiler/profilerthread.cpp Outdated Show resolved Hide resolved
src/profiler/profilerthread.cpp Outdated Show resolved Hide resolved
src/profiler/profiler.h Show resolved Hide resolved
Comment on lines -161 to +163
for (size_t n=0;n<modules.size();n++)
for (size_t m=0;m<modules.size();m++)
{
Module &mod = modules[n];
Module &mod = modules[m];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be too late for that, but generally it's better to place unrelated changes in separate commits. That would also provide for a place to describe why the change is done (i.e. which compiler warning is fixed if any), in the commit message.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assumed you'd prefer a single commit. I squashed what few separate commits I had into one before pushing, sorry about that.
The local variable name changes here and there are to fix class / outer scope variables being shadowed.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some good advice can be found by asking the right question:

https://www.google.com/search?q=when+to+commit+git

For instance:

You shouldn't commit based on a time basis, but on a feature basis. Whenever you add a new feature that's worth committing, commit. You added a working method? Commit. You fixed a typo? Commit. You fixed a file's wrong indentation? Commit. There's nothing wrong committing small changes, as soon as the commit is relevant.

What is wrong is committing a huge number of changes, with no relations between each others. It makes it very hard to detect the commit source of a given regression.

-- https://softwareengineering.stackexchange.com/a/74893/16481

// DE: 20090325 Threads now have CPU usage
ThreadInfo::ThreadInfo(DWORD id_, HANDLE thread_handle_)
: id(id_), thread_handle(thread_handle_)
std::wstring getThreadDescriptorName(HANDLE thread_handle)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Refactoring this function out also would ideally be done in its own commit.

src/wxProfilerGUI/CallstackView.cpp Outdated Show resolved Hide resolved
src/wxProfilerGUI/database.cpp Outdated Show resolved Hide resolved
src/wxProfilerGUI/CallstackView.cpp Outdated Show resolved Hide resolved
src/wxProfilerGUI/database.cpp Outdated Show resolved Hide resolved
Comment on lines -161 to +163
for (size_t n=0;n<modules.size();n++)
for (size_t m=0;m<modules.size();m++)
{
Module &mod = modules[n];
Module &mod = modules[m];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some good advice can be found by asking the right question:

https://www.google.com/search?q=when+to+commit+git

For instance:

You shouldn't commit based on a time basis, but on a feature basis. Whenever you add a new feature that's worth committing, commit. You added a working method? Commit. You fixed a typo? Commit. You fixed a file's wrong indentation? Commit. There's nothing wrong committing small changes, as soon as the commit is relevant.

What is wrong is committing a huge number of changes, with no relations between each others. It makes it very hard to detect the commit source of a given regression.

-- https://softwareengineering.stackexchange.com/a/74893/16481

src/wxProfilerGUI/database.cpp Outdated Show resolved Hide resolved
Comment on lines -135 to +144
struct ExclusivePred { bool operator () (const Database::Item &a, const Database::Item &b) { return a.exclusive < b.exclusive ; } };
struct InclusivePred { bool operator () (const Database::Item &a, const Database::Item &b) { return a.inclusive < b.inclusive ; } };
struct ExclusivePred { bool operator () (const Database::Item &a, const Database::Item &b) {
if (a.exclusive != b.exclusive)
return a.exclusive < b.exclusive;
return a.inclusive < b.inclusive;
} };
struct InclusivePred { bool operator () (const Database::Item &a, const Database::Item &b) {
if (a.inclusive != b.inclusive)
return a.inclusive < b.inclusive;
return a.exclusive < b.exclusive;
} };
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, but ideally should be in its own commit. As it is there is zero documentation about this improvement.

src/wxProfilerGUI/threadsview.cpp Show resolved Hide resolved
@CyberShadow
Copy link
Member

Great! Thank you, and I don't have any more suggestions :)

Since I have a good setup for it, I am going to try and massage the git history a bit to ungroup unrelated changes from the big commits and squash changes that are not relevant to the history.

@aaalexandrov
Copy link
Contributor Author

Thanks, if there's anything I missed, don't hesitate to say.
I'll probably do the issue about profiling newly spawned threads at some point, but it'll take me some time.

Use the other time datum as a secondary sort criteria.
- Record sample information for each thread

- Record thread names

- Remove IPCounts.txt, and instead reconstruct them at load time

- Bump file format version

- Add UI for viewing sample threads

- Add UI for filtering by selected threads
Speed up worst case merging/insertion behavior.
Copy link
Member

@CyberShadow CyberShadow left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let me know if you agree with my history refactoring and commit messages, and we can merge it.

threadHandles.push_back(mostBusy);
return threadHandles;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There might be a better way to silence this warning.

Depending on the compiler, sometimes wrapping the entire if expression in another set of parens does it.

@aaalexandrov
Copy link
Contributor Author

It looks great to me, thanks for separating the commits.

@CyberShadow CyberShadow merged commit 08937c1 into VerySleepy:master Aug 21, 2021
@CyberShadow
Copy link
Member

Thanks for the very nice contribution :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add filter by thread
2 participants