All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Ævar Arnfjörð Bjarmason" <avarab@gmail.com>
To: "René Scharfe" <l.s.r@web.de>
Cc: Git List <git@vger.kernel.org>, Junio C Hamano <gitster@pobox.com>
Subject: Re: [PATCH 9/9] mergesort: use ranks stack
Date: Tue, 18 Jan 2022 11:40:43 +0100	[thread overview]
Message-ID: <220118.86r195pb2b.gmgdl@evledraar.gmail.com> (raw)
In-Reply-To: <cf5053b9-451c-7db6-acff-aae41bfabed3@web.de>


On Tue, Jan 18 2022, René Scharfe wrote:

> Am 17.01.22 um 19:22 schrieb René Scharfe:
>> Am 17.01.22 um 18:43 schrieb Ævar Arnfjörð Bjarmason:
>>>
>>> On Fri, Oct 01 2021, René Scharfe wrote:
>>>
>>>
>>>> +/*
>>>> + * Perform an iterative mergesort using an array of sublists.
>>>> + *
>>>> + * n is the number of items.
>>>> + * ranks[i] is undefined if n & 2^i == 0, and assumed empty.
>>>> + * ranks[i] contains a sublist of length 2^i otherwise.
>>>> + *
>>>> + * The number of bits in a void pointer limits the number of objects
>>>> + * that can be created, and thus the number of array elements necessary
>>>> + * to be able to sort any valid list.
>>>> + *
>>>> + * Adding an item to this array is like incrementing a binary number;
>>>> + * positional values for set bits correspond to sublist lengths.
>>>> + */
>>>>  void *llist_mergesort(void *list,
>>>>  		      void *(*get_next_fn)(const void *),
>>>>  		      void (*set_next_fn)(void *, void *),
>>>>  		      int (*compare_fn)(const void *, const void *))
>>>>  {
>>>> -	unsigned long l;
>>>> -
>>>> -	if (!list)
>>>> -		return NULL;
>>>> -	for (l = 1; ; l *= 2) {
>>>> -		void *curr;
>>>> -		struct mergesort_sublist p, q;
>>>> +	void *ranks[bitsizeof(void *)];
>>>> +	size_t n = 0;
>>>> +	int i;
>>>>
>>>> -		p.ptr = list;
>>>> -		q.ptr = get_nth_next(p.ptr, l, get_next_fn);
>>>> -		if (!q.ptr)
>>>> -			break;
>>>> -		p.len = q.len = l;
>>>> +	while (list) {
>>>> +		void *next = get_next_fn(list);
>>>> +		if (next)
>>>> +			set_next_fn(list, NULL);
>>>> +		for (i = 0; n & (1 << i); i++)
>>>> +			list = llist_merge(ranks[i], list, get_next_fn,
>>>> +					   set_next_fn, compare_fn);
>>>> +		n++;
>>>> +		ranks[i] = list;
>>>> +		list = next;
>>>> +	}
>>>
>>> (Commenting on a commit integrated into v2.34.0)
>>>
>>> The aCC compiler on HP/UX notes:
>>>
>>>     "mergesort.c", line 67: warning #2549-D: variable "ranks" is used before its value is set
>>>                         list = llist_merge(ranks[i], list, get_next_fn,
>>>
>>> It's commenting on the ranks[i] within the for-loop-within-while-loop
>>> above.
>>
>> That would be a bug.  I think none of the array elements are read before
>> they are written -- but of course I'm biased.  Can that compiler show a
>> sequence that would lead to reading uninitialized data?  Or anyone else?
>>
>> Initializing the array would memset(3) 128 bytes on 32-bit systems and
>> 512 bytes on 64-bit systems.  Doing that everywhere just to appease a
>> confused compiler on a dying platform would be merciful, but still sad.
>
> Does the warning disappear if you add "ranks[0] = NULL;" before the while
> loop?  And if it does, has adding "if (n & 1) ranks[0] = NULL;" instead
> the same effect?

Both of those make the warning go away.

Anyway, if you think the pre-image in master now is fine let's leave it
as it is. There's no point in just trying to appease aCC here.

I just thought I'd send a quick mail about it because I was looking at
its warning output, most of those warnings point to obviously harmless
issues, but I thought this one *might* point to an actual logic error
(but didn't look carefully enough myself), so I thought I'd send a quick
note about it.

If you think not it's probably best just to leave the code as-is.

>>
>>>
>>>>
>>>> -		if (compare_fn(p.ptr, q.ptr) > 0)
>>>> -			list = curr = pop_item(&q, get_next_fn);
>>>> +	for (i = 0; n; i++, n >>= 1) {
>>>> +		if (!(n & 1))
>>>> +			continue;
>>>> +		if (list)
>>>> +			list = llist_merge(ranks[i], list, get_next_fn,
>>>> +					   set_next_fn, compare_fn);
>>>>  		else
>>>> -			list = curr = pop_item(&p, get_next_fn);
>>>> -
>>>> -		while (p.ptr) {
>>>> -			while (p.len || q.len) {
>>>> -				void *prev = curr;
>>>> -
>>>> -				if (!p.len)
>>>> -					curr = pop_item(&q, get_next_fn);
>>>> -				else if (!q.len)
>>>> -					curr = pop_item(&p, get_next_fn);
>>>> -				else if (compare_fn(p.ptr, q.ptr) > 0)
>>>> -					curr = pop_item(&q, get_next_fn);
>>>> -				else
>>>> -					curr = pop_item(&p, get_next_fn);
>>>> -				set_next_fn(prev, curr);
>>>> -			}
>>>> -			p.ptr = q.ptr;
>>>> -			p.len = l;
>>>> -			q.ptr = get_nth_next(p.ptr, l, get_next_fn);
>>>> -			q.len = q.ptr ? l : 0;
>>>> -
>>>> -		}
>>>> -		set_next_fn(curr, NULL);
>>>> +			list = ranks[i];
>>>>  	}
>>>>  	return list;
>>>>  }
>>>


  reply	other threads:[~2022-01-18 10:56 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-10-01  9:07 [PATCH 0/9] mergesort: improve tests and performance René Scharfe
2021-10-01  9:10 ` [PATCH 1/9] test-mergesort: use strbuf_getline() René Scharfe
2021-10-02  9:08   ` Ævar Arnfjörð Bjarmason
2021-10-02 16:56     ` René Scharfe
2021-10-01  9:11 ` [PATCH 2/9] test-mergesort: add sort subcommand René Scharfe
2021-10-01 20:26   ` Junio C Hamano
2021-10-01  9:12 ` [PATCH 3/9] test-mergesort: add test subcommand René Scharfe
2021-10-01 20:26   ` Junio C Hamano
2021-10-02  8:35     ` Ævar Arnfjörð Bjarmason
2021-10-03 10:15       ` René Scharfe
2021-10-03 17:33         ` Junio C Hamano
2021-10-07 20:00           ` René Scharfe
2021-10-08  4:04             ` [PATCH 10/9 v2] test-mergesort: use repeatable random numbers René Scharfe
2021-10-08  4:17               ` Jeff King
2021-10-08  7:23               ` Ævar Arnfjörð Bjarmason
2021-10-08 17:30                 ` René Scharfe
2021-10-08 19:00                   ` Ævar Arnfjörð Bjarmason
2021-10-03 10:15       ` [PATCH 3/9] test-mergesort: add test subcommand René Scharfe
2021-10-01  9:14 ` [PATCH 4/9] test-mergesort: add generate subcommand René Scharfe
2021-10-01  9:16 ` [PATCH 5/9] test-mergesort: add unriffle mode René Scharfe
2021-10-01  9:17 ` [PATCH 6/9] test-mergesort: add unriffle_skewed mode René Scharfe
2021-10-01  9:19 ` [PATCH 7/9] p0071: measure sorting of already sorted and reversed files René Scharfe
2021-10-01  9:19 ` [PATCH 8/9] p0071: test performance of llist_mergesort() René Scharfe
2021-10-01  9:22 ` [PATCH 9/9] mergesort: use ranks stack René Scharfe
2022-01-17 17:43   ` Ævar Arnfjörð Bjarmason
2022-01-17 18:22     ` René Scharfe
2022-01-18  5:07       ` René Scharfe
2022-01-18 10:40         ` Ævar Arnfjörð Bjarmason [this message]
2022-01-18 12:27           ` René Scharfe

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=220118.86r195pb2b.gmgdl@evledraar.gmail.com \
    --to=avarab@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=l.s.r@web.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.