Liste des Groupes | Revenir à cl c |
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).
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.
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".
Les messages affichés proviennent d'usenet.