Re: [PATCH 2/2] zstd: Backport Huffman speed improvement from upstream

From: Nick Terrell
Date: Tue Nov 21 2023 - 14:59:39 EST




> On Nov 21, 2023, at 12:23 PM, Linus Torvalds <torvalds@xxxxxxxxxxxxxxxxxxxx> wrote:
>
> !-------------------------------------------------------------------|
> This Message Is From an External Sender
>
> |-------------------------------------------------------------------!
>
> On Mon, 20 Nov 2023 at 16:52, Nick Terrell <nickrterrell@xxxxxxxxx> wrote:
>>
>> +/* Calls X(N) for each stream 0, 1, 2, 3. */
>> +#define HUF_4X_FOR_EACH_STREAM(X) \
>> + { \
>> + X(0) \
>> + X(1) \
>> + X(2) \
>> + X(3) \
>> + }
>> +
>> +/* Calls X(N, var) for each stream 0, 1, 2, 3. */
>> +#define HUF_4X_FOR_EACH_STREAM_WITH_VAR(X, var) \
>> + { \
>> + X(0, (var)) \
>> + X(1, (var)) \
>> + X(2, (var)) \
>> + X(3, (var)) \
>> + }
>> +
>
> What shitty compilers do you need to be compatible with?
>
> Because at least for Linux, the above is one single #define:
>
> #define FOUR(X,y...) do { \
> X(0,##y); X(1,##y); X(2,##y); X(3,##y); \
> } while (0)
>
> and it does the right thing for any number of arguments, ie
>
> FOUR(fn)
> FOUR(fn1,a)
> FOUR(fn2,a,b)
>
> expands to
>
> do { fn(0); fn(1); fn(2); fn(3); } while (0)
> do { fn1(0,a); fn1(1,a); fn1(2,a); fn1(3,a); } while (0)
> do { fn2(0,a,b); fn2(1,a,b); fn2(2,a,b); fn2(3,a,b); } while (0)
>
> so unless you need to support some completely garbage compiler
> upstream, please just do the single #define.

Upstream zstd maintains strict C89 compatibility. We do use compiler
extensions when available, but only when we can detect the feature and
provide a correct fallback when it isn’t available. E.g. __builtin_ctz().
Empty variadic macros fails our C89 compatibility CI, as well as our
Visual Studios CI [0].

We’ve discussed dropping C89 support. The consensus was that
if we were starting the project today we’d stick to C11, but that it is
worth keeping C89 support for Zstd. We’ve seen people compile
zstd in some wacky environments.

W.r.t. do { } while (0), our older Visual Studios CI jobs failed on the
do { } while (0) macros, because it complained about constant false
branches. However, it looks like our current Visual Studios CI jobs
accept do { } while (0) [1]. So I’ve opened an upstream issue to
modernize all of macros [2].

Best,
Nick Terrell

[0] https://github.com/terrelln/zstd/pull/3
[1] https://github.com/terrelln/zstd/pull/4
[2] https://github.com/facebook/zstd/issues/3830

> Linus