git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH] hex: use unsigned index for ring buffer

From
Junio C Hamano <gitster@pobox.com>
Date
Oct 24, 2016, 23:53 UTC
Message-ID
<xmqq60ohtib5.fsf@gitster.mtv.corp.google.com>
In-Reply-To
<b1f9054e-fadb-c2d3-bf95-00e88e1fb85b@web.de>
René Scharfe <l.s.r@web.de> writes:
Show 51 quoted lines
> 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.
Looks good to me.  Peff?
> 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..
I somehow share that feeling, too.
Previous: René ScharfeNext: Jeff King
Message 8 of 14 in “hex: use unsigned index for ring buffer”
  1. hex: use unsigned index for ring bufferRené Scharfe, Oct 23, 2016
  2. Jeff KingOct 23, 2016
  3. René ScharfeOct 23, 2016
  4. Jeff KingOct 24, 2016
  5. Junio C HamanoOct 24, 2016
  6. Junio C HamanoOct 24, 2016
  7. René ScharfeOct 24, 2016
  8. Junio C HamanoOct 24, 2016
  9. Jeff KingOct 25, 2016
  10. Junio C HamanoOct 25, 2016
  11. Jeff KingOct 25, 2016
  12. Junio C HamanoOct 25, 2016
  13. René ScharfeOct 26, 2016
  14. Junio C HamanoOct 26, 2016

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.