Deutsch English Français Italiano |
<vc41rl$1fhjd$1@dont-email.me> View for Bookmarking (what is this?) Look up another Usenet article |
Path: ...!weretis.net!feeder8.news.weretis.net!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail From: kegs@provalid.com (Kent Dickey) Newsgroups: comp.arch Subject: Re: Computer architects leaving Intel... Date: Sat, 14 Sep 2024 13:08:05 -0000 (UTC) Organization: provalid.com Lines: 95 Message-ID: <vc41rl$1fhjd$1@dont-email.me> References: <2024Aug30.161204@mips.complang.tuwien.ac.at> <vbcob9$dvp4$1@dont-email.me> <vbd6ia$e0ld$2@dont-email.me> <UxpCO.174965$Hld5.7714@fx15.iad> Injection-Date: Sat, 14 Sep 2024 15:08:05 +0200 (CEST) Injection-Info: dont-email.me; posting-host="32b3d55c6c9da8c6cff78c6be17ab806"; logging-data="1558125"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+U4eOU5upSvCKdbn667dLj" Cancel-Lock: sha1:6Z75rHwIMmQU2NNqJ+ILItNa1cc= X-Newsreader: trn 4.0-test76 (Apr 2, 2001) Originator: kegs@provalid.com (Kent Dickey) Bytes: 4021 In article <UxpCO.174965$Hld5.7714@fx15.iad>, Scott Lurndal <slp53@pacbell.net> wrote: >Bernd Linsel <bl1-thispartdoesnotbelonghere@gmx.com> writes: >>On 05.09.24 19:04, Terje Mathisen wrote: >>> One of my alternatives are >>> >>> unsigned u = start; // Cannot be less than zero >>> if (u) { >>> u++; >>> do { >>> u--; >>> data[u]... >>> while (u); >>> } >>> >>> This typically results in effectively the same asm code as the signed >>> version, except for a bottom JGE (Jump (signed) Greater or Equal instead >>> of JA (Jump Above or Equal, but my version is far more verbose. >>> >>> Alternatively, if you don't need all N bits of the unsigned type, then >>> you can subtract and check if the top bit is set in the result: >>> >>> for (unsigned u = start; (u & TOPBIT) == 0; u--) >>> >>> Terje >>> >> >>What about: >> >>for (unsigned u = start; u != ~0u; --u) > >This is the form we use most when we need >to work in reverse. > >> ... >> >>or even >> >>for (unsigned u = start; (int)u >= 0; --u) >> ... >> >>? >> >>I've compared all variants for x86_64 with -O3 -fexpensive-optimizations >>on godbolt.org: >>- 32 bit version: https://godbolt.org/z/TMhhx3nch >>- 64 bit version: https://godbolt.org/z/8oxzTf5Gf >> > >No significant differences in code generation for unsigned vs. signed. This discussion wandered into many subthreads, but I only want to make one post and chose here. When you write code working on signed numbers and do something like: (a < 0) || (a >= max) Then the compiler realizes if you treat 'a' as unsigned, this is just: (unsigned)a >= max since any negative number, treated as unsigned, will be larger than the largest positive signed number. So, to do loops which count down and have any stride using an unsigned loop count: for(u = start; u <= start; u -= step) With the usual caveats (start must be a valid signed number, and step cannot be so large that start + step crosses the signed boundary). But: unsigned numbers in C have some dangers, which no one here has mentioned. Some code presented comes CLOSE to being wrong, but gets lucky. With "int" being 32-bits, C promotion rules around unsigned ints, signed ints, and unsigned 64-bit can create trouble. uint64_t dval; uint32_t uval; int a; val32 = 1 dval = 1; a = 1; dval = val32 - 2 + dval; C will do (val32 - 2) first, with is (1U - 2) which is 0xffff_ffff, and then add dval, and the result is 0x1_0000_0000. Signed numbers don't have this risk, so if you're doing known small loops, you can just use ints. If you're doing possibly large loops, just use int64_t. Bringing it back to "architecture" Like Anton Ertl has said, LP64 for C/C++ is a mistake. It should always have been ILP64, and this nonsense would go away. Any new architecture should make C ILP64 (looking at you RISC-V, missing yet another opportunity to not make the same mistakes as everyone else). Kent