From: Pedro Alves <pedro@palves.net>
To: Simon Marchi <simark@simark.ca>,
Simon Marchi <simon.marchi@efficios.com>,
gdb-patches@sourceware.org
Subject: Re: [PATCH 12/12] gdb: use two displaced step buffers on amd64/Linux
Date: Sat, 28 Nov 2020 18:56:06 +0000 [thread overview]
Message-ID: <b108f8ff-b225-c86d-974a-2801a7c1a23a@palves.net> (raw)
In-Reply-To: <d6cb10f9-23d3-13f9-f1ef-9bb5b4d7ca5c@simark.ca>
On 11/26/20 9:43 PM, Simon Marchi wrote:
> On 2020-11-25 3:56 p.m., Simon Marchi wrote:
>> On 2020-11-25 3:07 p.m., Simon Marchi wrote:
>>> We still have to figure out why the performance regresses compared to
>>> master. One thing is that we still do an extra resume attempt each
>>> time. We do one resume where the disp step prepare succeeds and one
>>> more where it fails. That's twice as much work as before, where we did
>>> one successful prepare and then skipped the next ones. I'll make an
>>> experimental change such that the arch can say "the prepare worked, but
>>> now I'm out of buffer", just to see how that improves (or not)
>>> performance.
>>
>> That made just a small difference. Let's call this new patch E:
>>
>> #9 + A + B + C + D + E: 105,727
>
> Ok, I played a bit more with this and found a case where we do more
> work that may explain the difference.
>
> handle_signal_stop calls finish_step_over, which calls start_step_over.
> Let's say that the displaced step buffer is used by some thread and
> another thread either hits the breakpoint, we go into start_step_over to
> see if we can start a new step over. We can't, because the event thread
> isn't the one that is using the displaced stepping buffer, the buffer is
> still occupied.
>
> In the pre-patch code, that early check in start_step_over:
>
> /* If this inferior already has a displaced step in process,
> don't start a new one. */
> if (displaced_step_in_progress (tp->inf))
> continue;
>
> means that we won't even try one resumption, we'll skip over all threads
> in the chain (the only cost is the cost of iteration).
>
> In the patch I previously called "C", start_step_over starts with the
> assumption that the inferior has an available buffer, and needs to do at
> least one resumption attempt that returns "unavailable" before it
> assumes there are no more available. That one unnecessary resumption
> attempt happens over and over and ends up being costly.
>
> I changed my patch C to make the "unavailable" property persistent,
> instead of just using it locally in start_step_over. If a displaced
> step prepare returns "unavailable", we mark that this inferior has no
> more buffers available, and only reset this flag when a displaced step
> for this inferior finishes. Doing so, when a thread hits the breakpoint
> and start_step_over is called, the unavailable flag is already set.
> Last time we tried to prepare a displaced step, there were no buffers
> available. And if no displaced step finished for this inferior since,
> then why bother asking? As a result, we don't even try one resume if
> the buffers are already take, just like with the pre-patch code.
>
> I re-did some tests with the new patch C:
>
> master: 110,736
> 9: 19,973
> 9 + A + B + C: 107,711
> 9 + A + B + C + E: 111,135
> Everything up to
> using two displaced
> stepping buffers: 110,697
>
> Note that I dropped patch D, which was to break out of the
> start_step_over loop when getting "unavailable". It didn't help much
> and wasn't desired functionality anyway.
>
> And for the reminder, patch E is that when returning "_OK", the arch can
> also tell us "that was the last one, any more request would return
> unavailable". So that allows to do just one resumption attempt (at
> most) per start_step_over invocation, rather than 2.
>
> What this shows is that by using everything up to patch E, we are pretty
> much on par with the performance, but with the more flexible
> architecture. That makes sense, as (I think) we do pretty much the same
> work.
>
> Re-thinking about patch C and E, I'm thinking that we could let the
> architecture's displaced stepping implementation decide when it sets the
> "unavailable" flag, instead of the core of GDB setting it. The
> architecture would then choose the policy it wants to adopt:
>
> - set the flag when it used its last buffer (equivalent to patch E)
> - set the flag when it returns "_UNAVAILABLE" (equivalent to patch C')
> - never set the unavavaible flag (equivalent to patch 9)
>
> It also shows that using two buffers on x86-64 doesn't improve
> performance (unless there's another unfortunate bottleneck I haven't
> found). But that's what I expected. My hypothesis is that the actual
> step portion of the displaced step is so fast that we never really use
> the buffers in parallel. If we start two displaced steps, by the time
> we prepare the second one, the first one has already finished and is
> waiting for GDB to clean it up. If for some reason we could displaced
> step an instruction that took, say, 1 second to execute, then having
> many displaced step buffers would be useful, because GDB would be able
> to start them all and have them really run in parallel.
>
> I'll prepare a user branch with all those fixup patches so you can take
> a look, and if you think it makes sense I'll be ready for a v2.
I took a look and your branch, and it makes sense to me.
I run the perf test on my end, and the performance gap is practically
gone on my end as well. I'm happy with that.
prev parent reply other threads:[~2020-11-28 18:56 UTC|newest]
Thread overview: 44+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-11-10 21:46 [PATCH 00/12] Concurrent displaced stepping Simon Marchi via Gdb-patches
2020-11-10 21:46 ` [PATCH 01/12] gdb: add inferior_execd observable Simon Marchi via Gdb-patches
2020-11-25 1:28 ` Pedro Alves
2020-11-10 21:46 ` [PATCH 02/12] gdb: clear inferior displaced stepping state on exec Simon Marchi via Gdb-patches
2020-11-25 1:28 ` Pedro Alves
2020-12-01 4:27 ` Simon Marchi
2020-11-10 21:46 ` [PATCH 03/12] gdb: rename things related to step over chains Simon Marchi via Gdb-patches
2020-11-25 1:28 ` Pedro Alves
2020-11-25 13:16 ` Simon Marchi via Gdb-patches
2020-11-10 21:46 ` [PATCH 04/12] gdb: rename displaced_step_closure to displaced_step_copy_insn_closure Simon Marchi via Gdb-patches
2020-11-25 1:29 ` Pedro Alves
2020-11-10 21:46 ` [PATCH 05/12] gdb: rename displaced_step_fixup to displaced_step_finish Simon Marchi via Gdb-patches
2020-11-25 1:29 ` Pedro Alves
2020-11-10 21:46 ` [PATCH 06/12] gdb: introduce status enum for displaced step prepare/finish Simon Marchi via Gdb-patches
2020-11-11 23:36 ` Andrew Burgess
2020-11-25 13:17 ` Simon Marchi via Gdb-patches
2020-11-25 1:30 ` Pedro Alves
2020-11-25 13:20 ` Simon Marchi via Gdb-patches
2020-11-10 21:46 ` [PATCH 07/12] gdb: pass inferior to get_linux_inferior_data Simon Marchi via Gdb-patches
2020-11-25 1:30 ` Pedro Alves
2020-11-10 21:46 ` [PATCH 08/12] gdb: move displaced stepping types to displaced-stepping.{h, c} Simon Marchi via Gdb-patches
2020-11-25 1:30 ` Pedro Alves
2020-11-10 21:46 ` [PATCH 09/12] gdb: move displaced stepping logic to gdbarch, allow starting concurrent displaced steps Simon Marchi via Gdb-patches
2020-11-25 1:40 ` Pedro Alves
2020-11-25 19:29 ` Simon Marchi via Gdb-patches
2020-11-25 19:35 ` Simon Marchi
2020-11-26 14:25 ` Pedro Alves
2020-11-30 19:13 ` Simon Marchi via Gdb-patches
2020-11-26 14:24 ` Pedro Alves
2020-11-30 20:26 ` Simon Marchi
2020-11-10 21:46 ` [PATCH 10/12] gdb: change linux gdbarch data from post to pre-init Simon Marchi via Gdb-patches
2020-11-25 1:41 ` Pedro Alves
2020-11-10 21:46 ` [PATCH 11/12] gdb: make displaced stepping implementation capable of managing multiple buffers Simon Marchi via Gdb-patches
2020-11-25 1:41 ` Pedro Alves
2020-11-30 18:58 ` Simon Marchi
2020-11-30 19:01 ` Simon Marchi
2020-11-10 21:46 ` [PATCH 12/12] gdb: use two displaced step buffers on amd64/Linux Simon Marchi via Gdb-patches
2020-11-25 1:42 ` Pedro Alves
2020-11-25 6:26 ` Simon Marchi
2020-11-25 20:07 ` Simon Marchi
2020-11-25 20:56 ` Simon Marchi
2020-11-26 21:43 ` Simon Marchi
2020-11-26 22:34 ` Simon Marchi
2020-11-28 18:56 ` Pedro Alves [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=b108f8ff-b225-c86d-974a-2801a7c1a23a@palves.net \
--to=pedro@palves.net \
--cc=gdb-patches@sourceware.org \
--cc=simark@simark.ca \
--cc=simon.marchi@efficios.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox