| Deutsch English Français Italiano |
|
<vbpl36$30c4v$2@dont-email.me> View for Bookmarking (what is this?) Look up another Usenet article |
Path: ...!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: David Brown <david.brown@hesbynett.no>
Newsgroups: comp.lang.c
Subject: Re: Top 10 most common hard skills listed on resumes...
Date: Tue, 10 Sep 2024 16:28:54 +0200
Organization: A noiseless patient Spider
Lines: 136
Message-ID: <vbpl36$30c4v$2@dont-email.me>
References: <vab101$3er$1@reader1.panix.com> <vbhbbb$1blt4$1@dont-email.me>
<vbipp5$24kl5$1@paganini.bofh.team> <vbk0d9$1tajm$1@dont-email.me>
<vbkpfc$27l2o$1@paganini.bofh.team> <vbl3am$228vv$1@dont-email.me>
<vblfgb$2dkij$1@paganini.bofh.team> <vblhp7$249ug$1@dont-email.me>
<vbloje$2e34o$1@paganini.bofh.team> <vbmeae$2bn2v$2@dont-email.me>
<vbn8pe$2g9i6$2@paganini.bofh.team> <vbnaqt$2g0vc$1@dont-email.me>
<vbnre4$2h8k3$1@paganini.bofh.team> <vbor2f$2qqt1$1@dont-email.me>
<vbpj6o$2orhf$1@paganini.bofh.team>
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 7bit
Injection-Date: Tue, 10 Sep 2024 16:28:54 +0200 (CEST)
Injection-Info: dont-email.me; posting-host="164517e557401dcf9b3aeffde6d063fe";
logging-data="3158175"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/5vxVwHWDbXRwe6Vra3vtD2uSCMaE0iCs="
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101
Thunderbird/102.11.0
Cancel-Lock: sha1:cW2UDjWYirXg06Mk1XbsuXInC+k=
Content-Language: en-GB
In-Reply-To: <vbpj6o$2orhf$1@paganini.bofh.team>
Bytes: 9027
On 10/09/2024 15:56, Waldek Hebisch wrote:
> David Brown <david.brown@hesbynett.no> wrote:
>> On 10/09/2024 00:04, Waldek Hebisch wrote:
>>> David Brown <david.brown@hesbynett.no> wrote:
>>>> On 09/09/2024 18:46, Waldek Hebisch wrote:
>>>>> David Brown <david.brown@hesbynett.no> wrote:
>>>>>> On 09/09/2024 05:04, Waldek Hebisch wrote:
>>>>>>> Bart <bc@freeuk.com> wrote:
>>>>>>>> On 09/09/2024 01:29, Waldek Hebisch wrote:
>>>>>>>>> Bart <bc@freeuk.com> wrote:
>>>>>>>>
>>>>>>>>> No. It is essential for efficiency to have 32-bit types. On 32-bit
>>>>>>>>> machines doing otherwise would add useless instructions to object
>>>>>>>>> code. More precisly, really stupid compiler will generate useless
>>>>>>>>> intructions even with my declarations, really smart one will
>>>>>>>>> notice that variables fit in 32-bits and optimize accordingly.
>>>>>>>>> But at least some gcc versions needed such declarations. Note
>>>>>>>>> also that my version makes clear that there there is
>>>>>>>>> symmetry (everything should be added using 64-bit precision),
>>>>>>>>> you depend on promotion rules which creates visual asymetry
>>>>>>>>> are requires reasoning to realize that meaning is symetric.
>>>>>>>>
>>>>>>>> Your posted code used 64-bit aritmetic. The xext and c 32-bit variables
>>>>>>>> were used in loops where they need to be widened to 64 bits anyway. The
>>>>>>>> new value of c is set from a 32-bit result.
>>>>>>>
>>>>>>> Well, at C level there is 64-bit type. The intent is that C compiler
>>>>>>> should notice that the result is 32-bit + carry flag. Ideally
>>>>>>> compiler should notice that c has only one bit and can keep it
>>>>>>> in carry flag. On i386 comparison needed for loop control would
>>>>>>> destroy carry flag, so there must be code using value of carry in
>>>>>>> register and code to save carry to register. But one addition
>>>>>>> of highs parts can be skipped. On 32-bit ARM compiler can use
>>>>>>> special machine istructions and actually generated code which
>>>>>>> is close to optimal.
>>>>>>
>>>>>> When you have a type that you want to be at least 32 bits (to cover the
>>>>>> range you need), and want it to be as efficient as possible on 32-bit
>>>>>> and 64-bit machines (and 16-bit and 8-bit, still found in
>>>>>> microcontrollers), use "int_fast32_t". On x86-64 it will be 64-bit, on
>>>>>> 32-bit systems it will be 32-bit. Use of the [u]int_fastNN_t types can
>>>>>> make code significantly more efficient on 64-bit systems while retaining
>>>>>> efficiency on 32-bit (or even smaller) targets.
>>>>>
>>>>> Well, I have constraints, some of which are outside of C code.
>>>>> To resolve contraints I normally use some configure machinery.
>>>>> If a standard type is exact match for my constraints, then I would
>>>>> use standard type, possibly adding some fallbacks for pre-standard
>>>>> systems. But if my constranits differ, I see no advantage in
>>>>> using more "fancy" standard types compared to old types.
>>>>>
>>>>
>>>> The "fancy" standard types in this case specify /exactly/ what you
>>>> apparently want - a type that can deal with at least 32 bits for range,
>>>> and is as efficient as possible on different targets. What other
>>>> constraints do you have here that make "int_fast32_t" unsuitable?
>>>
>>> This routine is part of small library. Good approximation is that
>>> I want a type (posibly depending on target) which will make this
>>> library fast. As I wrote in another message I plan to use 64-bit
>>> units of work on 64-bit targets. I have not plans to use the
>>> library in 8-bit or 16-bit targets, but if I needed them on such
>>> targets I probably would use 16-bit work unit. So, while 32-bit
>>> work unit represents current state, it not correct statement of
>>> intentions. Consequently, 'int_fast32_t' would be as misleading
>>> or more misleading than 'int' ('int' is reasonable indication
>>> that choice of types is not finished, 'int_fast32_t' suggest that
>>> it is proper choice for all targets).
>>
>> So you really want to say "at least 16 bits, as efficiently as possible"
>> - the type then is "int_fast16_t". This should be 32-bit or 64-bit on
>> most architectures bigger than 16-bit - unless the target is actually
>> more efficient at handling 16-bit (such as the original 68000).
>
> As I wrote I have other constrants that are likely to favour 32 bits
> on 32-bit machines and 64-bit on 64-bit machines. As you noticed
> "int_fast16_t" may be 16 bit even if native word size is bigger.
> And concerning proper size for "int_fast16_t", it is enough that
> CPU performs scalar operations with the same speed regardless
> of size of operands (including mixed operands). Then there is
> no reason to favour bigger size. And there are reasons to favour
> smaller size, like cache use or opportunities for autovectorization.
> So I would make "int_fast16_t" into 16-bit type on such a machine.
>
On many cpus, using sizes smaller than the full register size means
doing sign extensions or masking operations at various times - thus full
size register operations can often be more efficient. On such systems
you will find that int_fast16_t is 32-bit or 64-bit, according to the
register width. On other cpus, some common ALU operations on full-size
operands can be slower than for smaller operands (such as on the 68000).
There, int_fast16_t will be 16-bit.
Compiler authors know what will usually be faster on the target. There
will always be some exceptions (division is usually faster on smaller
operands, for example). But if you don't know the target - as is the
case of portable code - the compiler will usually make a better choice
here than you would.
> So, I could use "int_fastX_t" with X determined by my constranits,
> but assuming "int_fastX_t = int_fast16_t" would be a latent bug.
The point is to /avoid/ assumptions, not make new ones.
>
>> If something like that is not sufficient, because you want more
>> flexibility, then consider making a typedef with a name you find
>> suitable, and a using that. You can have pre-processor conditional
>> compilation to handle known cases, and fall back to int_fast16_t otherwise.
>
> As I wrote, I want type to be determined by configuration machinery.
> And configuration machinery will generate appropriate typedefs.
>
>> The answer to "I don't know if this is the best choice on all targets,
>> including ones I haven't tried" is /not/ "I'll use this type that I know
>> is not the most efficient on targets that I /have/ tried".
>
> Actually, main use case is when I know _a lot_ about targets. Concerning
> other targets, they are "to do", when I came to them, standard types
> _may_ give useful baseline.
>
> And to put a bit differently what I wrote previously, consider
> 'int' in current code as big shouting "FIXME". I have different
> things to fix first, and I want a proper fix, so delay with this
> one.
>
I would tend to use "int" when I meant "int", "int_fast16_t" when I
meant "int_fast16_t", and "// FIXME" when I meant "FIXME". But it's
your code, and you use the style you want. I've given you advice on
better choices of types, along with details of how they work in
practice, and what guarantees you get from the standards. If you still
prefer less efficient code, it's your choice.