Path: ...!news.nobody.at!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail From: BGB 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 05:05:46 -0500 Organization: A noiseless patient Spider Lines: 260 Message-ID: References: <877cdur1z9.fsf@bsb.me.uk> <871q42qy33.fsf@bsb.me.uk> <87ed82p28y.fsf@bsb.me.uk> <87r0c1nzjj.fsf@bsb.me.uk> <87ikxconq4.fsf@bsb.me.uk> <20240711115418.00001cdf@yahoo.com> <20240712154252.00005c2f@yahoo.com> <86o7717jj1.fsf@linuxsc.com> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit Injection-Date: Thu, 18 Jul 2024 12:05:50 +0200 (CEST) Injection-Info: dont-email.me; posting-host="aa3779b5b5223d49c4a316d45303c75e"; logging-data="2497517"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+k8qADpWOr2qBiXf7MJyceXtbxD4BT+II=" User-Agent: Mozilla Thunderbird Cancel-Lock: sha1:GWbn+5p7MKtGMxbBvtEb0Uwxizc= In-Reply-To: Content-Language: en-US Bytes: 10330 On 7/18/2024 2:46 AM, David Brown wrote: > On 17/07/2024 19:53, BGB wrote: >> On 7/17/2024 6:38 AM, Bart wrote: >>> On 13/07/2024 10:39, BGB wrote: >>> >>>> But, as I see it, no real point in arguing this stuff (personally, I >>>> have better stuff to be doing...). >>> >>> We all do. But this group seems to be about arguing about pointless >>> stuff and you might come here when you want a respite from proper work. >>> >>> However (here I assume you've gone back to Quake but that other >>> interested parties might be reading this), consider the program below. >>> >> >> I got back to debugging... > > To be clear - you are talking about debugging your compiler here, yes? > My compiler and my Quake 3 port, but most of the bugs in the Quake 3 port thus far were due to bugs either in my compiler or in the runtime libraries. >> >> Ironically, one of the big bugs I ended up finding was related to >> internal struct handling "leaking through" and negatively effecting >> stuff. >> >> say: >>    typedef struct foo_s foo_t;  // don't care what it contains for now. >> >>    foo_t arr[...]; >>    foo_t temp; >>    int i, j; >>    ... >>    temp=arr[i]; >>    arr[i]=arr[j]; >>    arr[j]=temp; >> >> Internally, it would load a reference to arr[i] into temp, but then >> this location would get overwritten before the third assignment >> happened, causing the incorrect contents to be copied to arr[j]. >> >> For now, have ended up changing stuff such that any struct-assignment >> (for structs in the "by-ref" category) to a local variable will >> instead copy the contents to the memory location associated with that >> struct. > > How could it possibly mean anything else?  Structs in C are objects - > contiguous blocks of bytes interpreted by a type.  Assigning them will > mean copying those bytes.  Pretending the language sometimes means > structs and sometimes means magical auto-dereferencing pointers to > structs is simply wrong. > The "magical auto dereferencing pointers" interpretation gives better performance, when it works. In this case, it didn't work... 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. Because, it turned out this was buggy and Quake 3 essentially stepped on this issue here. The bug wasn't the intended behavior in this case, but was in effect a bug. > If "foo_t" is 2000 bytes long, then "foo_t temp" makes a 2000 byte space > in your local variables (the stack, on virtually every platform) and > "temp = arr[i];" does a 2000 byte memcpy().  The same thing applies if > "foo_t" is 2 bytes long, or 2 megabytes long.  And if there is a stack > overflow making "temp", that's the programmer's problem. > For now: 1 - 16 bytes, goes in registers, except when accessing a member where it needs to be in-memory; unless it is a SIMD type which is special and allows accessing members with the value still in registers. 17 bytes to 15.999K: Accessed by an implicit reference, uses hidden copying to mimic by-value semantics (not quite foolproof as of yet it seems). 16K and beyond, quietly turned into a heap allocation (with a compiler warning). Should otherwise look the same as the prior case. > It is only once that is all working properly and reliably that you can > begin to think about optimisation - code that gives the same observable > behaviour "as if" you had direct translation, but is more efficient. > Maybe your target architecture has a way to make a "memswap()" function > that is more efficient than two "memcpy()" calls, and you can use that. > I did implement such a function, and ended up using it in the "qsort()" function (also ended up beating on this as it was also misbehaving). <---- /* Swap two items in memory. */ void _memswap(void *ptra, void *ptrb, int sz) { u64 v0, v1, v2, v3; byte *csa, *csb; int n; csa=ptra; csb=ptrb; n=sz; while(n>=16) { v0=((u64 *)csa)[0]; v2=((u64 *)csb)[0]; v1=((u64 *)csa)[1]; v3=((u64 *)csb)[1]; ((u64 *)csb)[0]=v0; ((u64 *)csa)[0]=v2; ((u64 *)csb)[1]=v1; ((u64 *)csa)[1]=v3; csa+=16; csb+=16; n-=16; } if(n>=8) { v0=((u64 *)csa)[0]; v2=((u64 *)csb)[0]; ((u64 *)csb)[0]=v0; ((u64 *)csa)[0]=v2; csa+=8; csb+=8; n-=8; } if(!n) return; if(n>=4) { v0=((u32 *)csa)[0]; v2=((u32 *)csb)[0]; ((u32 *)csb)[0]=v0; ((u32 *)csa)[0]=v2; csa+=4; csb+=4; n-=4; } if(n) { while(n>0) { v0=csa[0]; v1=csb[0]; csb[0]=v0; csa[0]=v1; csa++; csb++; n--; } } } ----> But, Quake 3 had used struct-assignment for swapping values, and had ========== REMAINDER OF ARTICLE TRUNCATED ==========