Deutsch   English   Français   Italiano  
<v7be8i$2g3q4$1@dont-email.me>

View for Bookmarking (what is this?)
Look up another Usenet article

Path: ...!2.eu.feeder.erje.net!feeder.erje.net!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: =?UTF-8?Q?Re=3a_technology_discussion_=e2=86=92_does_the_world_need?=
 =?UTF-8?B?IGEgIm5ldyIgQyA/?=
Date: Thu, 18 Jul 2024 18:01:21 +0200
Organization: A noiseless patient Spider
Lines: 128
Message-ID: <v7be8i$2g3q4$1@dont-email.me>
References: <v66eci$2qeee$1@dont-email.me> <v6jiud$1dsjb$1@dont-email.me>
 <877cdur1z9.fsf@bsb.me.uk> <v6joi4$1epoj$1@dont-email.me>
 <871q42qy33.fsf@bsb.me.uk> <v6k6i0$1h4d3$1@dont-email.me>
 <87ed82p28y.fsf@bsb.me.uk> <v6m03l$1tf05$1@dont-email.me>
 <87r0c1nzjj.fsf@bsb.me.uk> <v6m716$1urj4$1@dont-email.me>
 <87ikxconq4.fsf@bsb.me.uk> <v6n8iu$24af0$1@dont-email.me>
 <20240711115418.00001cdf@yahoo.com> <v6oamt$2d8nn$1@dont-email.me>
 <v6oct4$2djgq$2@dont-email.me> <v6of96$2ekb0$1@dont-email.me>
 <v6ovfc$2hcpf$1@dont-email.me> <v6p4hf$2icph$1@dont-email.me>
 <v6qgpu$2t6p7$3@dont-email.me> <v6r33m$30grj$1@dont-email.me>
 <20240712154252.00005c2f@yahoo.com> <86o7717jj1.fsf@linuxsc.com>
 <v6ti10$3gru4$1@dont-email.me> <v78af7$1qkuf$1@dont-email.me>
 <v790f2$1up8s$1@dont-email.me> <v7ah7p$2ak85$1@dont-email.me>
 <v7apdt$2c6vd$1@dont-email.me> <v7b2i5$2dtpm$1@dont-email.me>
 <v7b3ki$2dg7u$1@dont-email.me>
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 8bit
Injection-Date: Thu, 18 Jul 2024 18:01:23 +0200 (CEST)
Injection-Info: dont-email.me; posting-host="5e58e10ba9a4731c305671ca05dd8458";
	logging-data="2625348"; mail-complaints-to="abuse@eternal-september.org";	posting-account="U2FsdGVkX1/8dF+Nu2gxwM5+OjepFNjQ1Sk8/aVU5ro="
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101
 Thunderbird/102.11.0
Cancel-Lock: sha1:tXmuX8YLrYqQmtMgJaDRiNXspQ0=
Content-Language: en-GB
In-Reply-To: <v7b3ki$2dg7u$1@dont-email.me>
Bytes: 8338

On 18/07/2024 15:00, Bart wrote:
> On 18/07/2024 13:41, David Brown wrote:
>> On 18/07/2024 12:05, BGB wrote:
> 
>>> The "magical auto dereferencing pointers" interpretation gives better 
>>> performance, when it works. In this case, it didn't work...
>>
>> It's very easy to make high performance code if correctness doesn't 
>> matter!  Obviously, correctness is more important.
> 
> It is useful to explore ways of making some scenarios faster. Here there 
> is simply a bug in one of those ways. But you don't just give up 
> completely; you can try fixing the bug.

Sure.  But correctness is more important than speed, especially in a 
tool that other people rely on for correctness like a compiler.  You 
don't have optimisations unless you are completely sure that they are 
always correct, even for the most inconvenient source code.

Of course you can have experimental optimisations when playing around or 
testing - perhaps enabled with flags that make it clear that they might 
be flawed, or that they only work for a restricted subset of C code.  I 
don't mean you should not try out new stuff and then find and fix the 
problems - of course you should!  But if a tool is going to be useful, 
priority one must be to make it give correct results, rather than give 
fast results.

> 
>>>
>>> Sadly, there is no good way at the moment to know whether or not it 
>>> will work, for now forcing the slower and more conservative option.
>>
>> I would think the simple test is that for data that is never changed 
>> (or not changed within the function), you can use a constant reference 
>> - otherwise you cannot.  It is not by coincidence that in C++, it is 
>> common to use pass by /const/ reference as an efficient alternative to 
>> pass by value for big objects.
> 
> You said the other day that my C compiler was wrong to do that: to use 
> efficient pass-by-pointer for structs marked as 'const' in the function 
> signature; they always have to be copied no matter what.
> 

No, it is fine to omit copies if you (the compiler) /know/ something 
cannot change.  And it is also good practice for programmers to use 
"const" to mark things that should not be changed.  But unfortunately 
the compiler can't be sure that a const pointer (or const reference in 
C++) cannot be cast to a non-const pointer.  Using a const pointer or 
reference makes it harder for a programmer to change the object 
accidentally, but does not make it impossible for them to change it 
intentionally.  And the compiler has to believe the worst case here, and 
can't optimise on the assumption that the thing pointed to with a const 
pointer remains unchanged by an external function.  However, if it can 
see the definition of the function and can see that it cannot change, 
then it can use that information for optimisation - regardless of the 
const or lack of const in the pointer.

(I'd prefer if "const" were a stronger promise in C and C++.  But I 
don't make the rules.)

>>
>> The normal system is that local objects are data on the stack - 
>> regardless of the size or type, scaler or aggregate.  Parameter 
>> passing is done by register for some types (for the first few 
>> parameters), or the stack otherwise.  Returns are in a register or two 
>> for some times, or by a stack slot assigned by the caller.  For struct 
>> parameters or return values, it can be efficient for the caller to 
>> pass hidden pointers, but that's not strictly necessary if you have a 
>> fixed stack frame layout.  (Struct parameters still get copied to the 
>> stack to ensure value semantics - the hidden pointer points to the 
>> stack copy.)
>>
>> Trying to have special cases for different sizes,
> 
> That's exactly what common 64-bit ABIs do. In fact the SYS V ABI is so 
> complicated that I can't understand its struct passing rules at all.
> 

It is what every ABI I know of does - from 8-bit to 64-bit.  They vary 
significantly in how much data is passed in registers, and when structs 
are passed in registers or on the stack.  (Older ABI's passed more on 
the stack - newer ones use registers more.  Passing small structs in 
registers became a lot more important as C++ gained popularity.)

I agree that the SYS V x86_64 ABI is very complicated.  So is the Win64 
x86_64 ABI, with different kinds of complications.

> (If I ever have to use that, I'd need to write test code for each 
> possible size of struct, up to 100 bytes or so (past the largest machine 
> register), and see how an existing compliant compiler handles each case.)
> 
> Here the context appears to be a custom ISA, so anything is possible.

Sure.

> 
>> You are trying to be too smart here, IMHO - the compiler's job is to 
>> let the programmer be smart.  It's always nice to have optimisations, 
>> but not at the expense of correctness.
> 
> That's an odd remark from a devotee of gcc. Your usual attitude is to 
> let the programmer write code in the most natural manner, and let a 
> smart optimising compiler sort it out.

Touché :-)

Compilers can get smarter once you have them simple and correct.  /Too/ 
smart - generating efficient but sometimes incorrect code - is not helpful.

And some decisions are always up to the programmer in C, regardless of 
how good the compiler optimisation is.  If the programmer makes a local 
variable, they expect it to be in a register, optimised away, or on the 
stack.  They don't expect the function to call malloc() and free() in 
some hidden manner.  And if they want to pass a struct by reference, 
they use a pointer (that's all you've fot in C) - if they pass the 
struct by value, they expect value semantics.

The smaller stuff can be optimised freely by the compiler, but the big 
decisions are made by the programmer.

And note that these two features of BGB's compiler under discussion - 
putting big locals on the heap and using hidden pointers for structs - 
are /not/ optimisations.  Putting locals on the heap is a pessimisation, 
making code bigger and slower.  And using references for passing structs 
which must logically be passed by value is not an optimisation either, 
because it changes the semantics of the language.