From: "René Scharfe" <l.s.r@web.de>
To: Junio C Hamano <gitster@pobox.com>, Jeff King <peff@peff.net>
Cc: Git List <git@vger.kernel.org>
Subject: Re: [PATCH] hex: use unsigned index for ring buffer
Date: Tue, 25 Oct 2016 00:33:03 +0200 [thread overview]
Message-ID: <b1f9054e-fadb-c2d3-bf95-00e88e1fb85b@web.de> (raw)
In-Reply-To: <xmqqshrl7j42.fsf@gitster.mtv.corp.google.com>
Am 24.10.2016 um 19:27 schrieb Junio C Hamano:
> Junio C Hamano <gitster@pobox.com> writes:
>
>>> I think it would be preferable to just fix it inline in each place.
>>
>> Yeah, probably.
>>
>> My initial reaction to this was
>>
>> char *sha1_to_hex(const unsigned char *sha1)
>> {
>> - static int bufno;
>> + static unsigned int bufno;
>> static char hexbuffer[4][GIT_SHA1_HEXSZ + 1];
>> return sha1_to_hex_r(hexbuffer[3 & ++bufno], sha1);
>>
>> "ah, we do not even need bufno as uint; it could be ushort or even
>> uchar". If this were a 256 element ring buffer and the index were
>> uchar, we wouldn't even be having this discussion, and "3 &" is a
>> way to get a fake type that is a 2-bit unsigned integer that wraps
>> around when incremented.
>>
>> But being explicit, especially when we know that we can rely on the
>> fact that the compilers are usually intelligent enough, is a good
>> idea, I would think.
>>
>> Isn't size_t often wider than uint, by the way? It somehow makes me
>> feel dirty to use it when we know we only care about the bottom two
>> bit, especially with the explicit "bufno %= ARRAY_SIZE(hexbuffer)",
>> but I may be simply superstitious in this case. I dunno.
>
> If we are doing the wrap-around ourselves, I suspect that the index
> should stay "int" (not even unsigned), as that is supposed to be the
> most natural and performant type on the architecture. Would it
> still result in better code to use size_t instead?
Right.
Gcc emits an extra cltq instruction for x86-64 (Convert Long To Quad,
i.e. 32-bit to 64-bit) if we wrap explicitly and still use an int in
sha1_to_hex(). It doesn't if we use an unsigned int or size_t. It
also doesn't for get_pathname(). I guess updating the index variable
only after use makes the difference there.
But I think we can ignore that; it's just an extra cycle. I only
even noticed it when verifying that "% 4" is turned into "& 3"..
Clang and icc don't add the cltq, by the way.
So how about this? It gets rid of magic number 3 and works for array
size that's not a power of two. And as a nice side effect it can't
trigger a signed overflow anymore.
Just adding "unsigned" looks more attractive to me for some reason.
Perhaps I stared enough at the code to get used to the magic values
there..
René
---
hex.c | 3 ++-
path.c | 3 ++-
2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/hex.c b/hex.c
index ab2610e..845b01a 100644
--- a/hex.c
+++ b/hex.c
@@ -78,7 +78,8 @@ char *sha1_to_hex(const unsigned char *sha1)
{
static int bufno;
static char hexbuffer[4][GIT_SHA1_HEXSZ + 1];
- return sha1_to_hex_r(hexbuffer[3 & ++bufno], sha1);
+ bufno = (bufno + 1) % ARRAY_SIZE(hexbuffer);
+ return sha1_to_hex_r(hexbuffer[bufno], sha1);
}
char *oid_to_hex(const struct object_id *oid)
diff --git a/path.c b/path.c
index a8e7295..52d889c 100644
--- a/path.c
+++ b/path.c
@@ -25,7 +25,8 @@ static struct strbuf *get_pathname(void)
STRBUF_INIT, STRBUF_INIT, STRBUF_INIT, STRBUF_INIT
};
static int index;
- struct strbuf *sb = &pathname_array[3 & ++index];
+ struct strbuf *sb = &pathname_array[index];
+ index = (index + 1) % ARRAY_SIZE(pathname_array);
strbuf_reset(sb);
return sb;
}
--
2.10.1
next prev parent reply other threads:[~2016-10-24 22:33 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-10-23 9:00 [PATCH] hex: use unsigned index for ring buffer René Scharfe
2016-10-23 9:11 ` Jeff King
2016-10-23 17:57 ` René Scharfe
2016-10-24 13:00 ` Jeff King
2016-10-24 17:15 ` Junio C Hamano
2016-10-24 17:27 ` Junio C Hamano
2016-10-24 22:33 ` René Scharfe [this message]
2016-10-24 23:53 ` Junio C Hamano
2016-10-25 0:30 ` Jeff King
2016-10-25 18:28 ` Junio C Hamano
2016-10-25 18:33 ` Jeff King
2016-10-25 18:37 ` Junio C Hamano
2016-10-26 17:08 ` René Scharfe
2016-10-26 17:53 ` Junio C Hamano
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=b1f9054e-fadb-c2d3-bf95-00e88e1fb85b@web.de \
--to=l.s.r@web.de \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=peff@peff.net \
/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;
as well as URLs for NNTP newsgroup(s).