All of lore.kernel.org
 help / color / mirror / Atom feed
From: David Howells <dhowells@redhat.com>
To: Thomas Gleixner <tglx@linutronix.de>
Cc: dhowells@redhat.com, linux-fsdevel@vger.kernel.org,
	linux-afs@lists.infradead.org, linux-kernel@vger.kernel.org
Subject: Re: [RFC PATCH 04/11] Add a function to start/reduce a timer
Date: Thu, 09 Nov 2017 00:33:21 +0000	[thread overview]
Message-ID: <8077.1510187601@warthog.procyon.org.uk> (raw)
In-Reply-To: <alpine.DEB.2.20.1710201359480.2908@nanos>

Thomas Gleixner <tglx@linutronix.de> wrote:

> > +extern int reduce_timer(struct timer_list *timer, unsigned long expires);
> 
> For new timer functions we really should use the timer_xxxx()
> convention. The historic naming convention is horrible.
> 
> Aside of that timer_reduce() is kinda ugly but I failed to come up with
> something reasonable as well.

reduce_timer() sounds snappier, probably because the verb is first, but I can
make it timer_reduce() if you prefer.  Or maybe timer_advance() - though
that's less clear as to the direction.

> > +		if (options & MOD_TIMER_REDUCE) {
> > +			if (time_before_eq(timer->expires, expires))
> > +				return 1;
> > +		} else {
> > +			if (timer->expires == expires)
> > +				return 1;
> > +		}
> 
> This hurts the common networking optimzation case. Please keep that check
> first:

The way the code stands, it doesn't make much difference because compiler
optimises away the MOD_TIMER_REDUCE case for __mod_timer() and optimises away
the other branch for reduce_timer().

> 		if (timer->expires == expires)
> 			return 1;
> 
> 		if ((options & MOD_TIMER_REDUCE) &&
> 		    time_before(timer->expires, expires))
> 		    	return 1;
> 
> Also please check whether it's more efficient code wise to have that option
> thing or if an additional 'bool reduce' argument cerates better code.

It's a constant passed into an inline function - gcc-7's optimiser copes with
that for x86_64 at least.  mod_timer() contains:

   0xffffffff810bb7a0 <+31>:    cmpq   $0x0,0x8(%rdi)
   0xffffffff810bb7a5 <+36>:    mov    %rsi,%r12
   0xffffffff810bb7a8 <+39>:    mov    %rdi,%rbx
   0xffffffff810bb7ab <+42>:    je     0xffffffff810bb829 <mod_timer+168>
   0xffffffff810bb7ad <+44>:    cmp    0x10(%rdi),%rsi
   0xffffffff810bb7b1 <+48>:    movl   $0x1,-0x38(%rbp)
   0xffffffff810bb7b8 <+55>:    je     0xffffffff810bba9f <mod_timer+798>

and reduce_timer() contains:

   0xffffffff810bbaed <+31>:    cmpq   $0x0,0x8(%rdi)
   0xffffffff810bbaf2 <+36>:    mov    %rsi,%r13
   0xffffffff810bbaf5 <+39>:    mov    %rdi,%rbx
   0xffffffff810bbaf8 <+42>:    je     0xffffffff810bbb9d <reduce_timer+207>
   0xffffffff810bbafe <+48>:    cmp    0x10(%rdi),%rsi
   0xffffffff810bbb02 <+52>:    mov    $0x1,%r14d
   0xffffffff810bbb08 <+58>:    jns    0xffffffff810bbe23 <reduce_timer+853>

As you can see, the relevant jump instruction is JE in one and JNS in the
other.

If I make the change you suggest with the equality check being unconditional,
mod_timer() is unchanged and reduce_timer() then contains:

   0xffffffff810bbaed <+31>:    cmpq   $0x0,0x8(%rdi)
   0xffffffff810bbaf2 <+36>:    mov    %rsi,%r13
   0xffffffff810bbaf5 <+39>:    mov    %rdi,%rbx
   0xffffffff810bbaf8 <+42>:    je     0xffffffff810bbba9 <reduce_timer+219>
   0xffffffff810bbafe <+48>:    mov    0x10(%rdi),%rax
   0xffffffff810bbb02 <+52>:    mov    $0x1,%r14d
   0xffffffff810bbb08 <+58>:    cmp    %rax,%rsi
   0xffffffff810bbb0b <+61>:    je     0xffffffff810bbe2f <reduce_timer+865>
   0xffffffff810bbb11 <+67>:    cmp    %rax,%rsi
   0xffffffff810bbb14 <+70>:    jns    0xffffffff810bbe2f <reduce_timer+865>

which smacks of a missed optimisation, since timer_before_eq() covers the ==
case.  Doing:

		long diff = timer->expires - expires;
		if (diff == 0)
			return 1;
		if (options & MOD_TIMER_REDUCE &&
		    diff <= 0)
			return 1;

gets me the same code in mod_timer() and the following in reduce_timer():

   0xffffffff810bbaed <+31>:    cmpq   $0x0,0x8(%rdi)
   0xffffffff810bbaf2 <+36>:    mov    %rsi,%r13
   0xffffffff810bbaf5 <+39>:    mov    %rdi,%rbx
   0xffffffff810bbaf8 <+42>:    je     0xffffffff810bbba3 <reduce_timer+213>
   0xffffffff810bbafe <+48>:    mov    0x10(%rdi),%rax
   0xffffffff810bbb02 <+52>:    mov    $0x1,%r14d
   0xffffffff810bbb08 <+58>:    sub    %rsi,%rax
   0xffffffff810bbb0b <+61>:    test   %rax,%rax
   0xffffffff810bbb0e <+64>:    jle    0xffffffff810bbe29 <reduce_timer+859>

which is marginally better - though I think it could still be optimised
better by the compiler.

Actually, something that might increase efficiency overall is to make
add_timer() an inline and forego the check - but that's a separate matter.

Thanks,
David

  reply	other threads:[~2017-11-09  0:33 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-09-01 15:40 [RFC PATCH 01/11] workqueue: Add a decrement-after-return and wake if 0 facility David Howells
2017-09-01 15:41 ` [RFC PATCH 02/11] refcount: Implement inc/decrement-and-return functions David Howells
2017-09-01 16:42   ` Peter Zijlstra
2017-09-01 21:15     ` David Howells
2017-09-01 21:50       ` Peter Zijlstra
2017-09-01 22:03         ` Peter Zijlstra
2017-09-01 22:51         ` David Howells
2017-09-04  7:30           ` Peter Zijlstra
2017-09-04 15:36   ` Christoph Hellwig
2017-09-04 16:08     ` David Howells
2017-09-05  6:45       ` Christoph Hellwig
2017-09-01 15:41 ` [RFC PATCH 03/11] Pass mode to wait_on_atomic_t() action funcs and provide default actions David Howells
2017-09-01 15:41 ` [RFC PATCH 04/11] Add a function to start/reduce a timer David Howells
2017-10-20 12:20   ` Thomas Gleixner
2017-11-09  0:33     ` David Howells [this message]
2017-09-01 15:41 ` [RFC PATCH 05/11] afs: Lay the groundwork for supporting network namespaces David Howells
2017-09-01 15:41 ` [RFC PATCH 06/11] afs: Add some protocol defs David Howells
2017-09-01 15:41 ` [RFC PATCH 07/11] afs: Update the cache index structure David Howells
2017-09-01 15:41 ` [RFC PATCH 08/11] afs: Keep and pass sockaddr_rxrpc addresses rather than in_addr David Howells
2017-09-01 15:41 ` [RFC PATCH 09/11] afs: Allow IPv6 address specification of VL servers David Howells
2017-09-01 15:42 ` [RFC PATCH 10/11] afs: Overhaul cell database management David Howells
2017-09-01 15:42 ` [RFC PATCH 11/11] afs: Retry rxrpc calls with address rotation on network error David Howells
2017-09-01 15:52 ` [RFC PATCH 00/11] AFS: Namespacing part 1 David Howells
2017-09-05 13:29 ` [RFC PATCH 01/11] workqueue: Add a decrement-after-return and wake if 0 facility Tejun Heo
2017-09-05 14:50   ` David Howells
2017-09-06 14:51     ` Tejun Heo

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=8077.1510187601@warthog.procyon.org.uk \
    --to=dhowells@redhat.com \
    --cc=linux-afs@lists.infradead.org \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=tglx@linutronix.de \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.