Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #147185 > unrolled thread
| Started by | jacobnavia <jacob@jacob.remcomp.fr> |
|---|---|
| First post | 2019-10-24 08:03 +0200 |
| Last post | 2019-10-27 13:05 +0100 |
| Articles | 20 on this page of 65 — 15 participants |
Back to article view | Back to comp.lang.c
Bit field usage jacobnavia <jacob@jacob.remcomp.fr> - 2019-10-24 08:03 +0200
Re: Bit field usage Joe Pfeiffer <pfeiffer@cs.nmsu.edu> - 2019-10-24 10:15 -0600
Re: Bit field usage jacobnavia <jacob@jacob.remcomp.fr> - 2019-10-24 18:55 +0200
Re: Bit field usage Joe Pfeiffer <pfeiffer@cs.nmsu.edu> - 2019-10-24 21:28 -0600
Re: Bit field usage scott@slp53.sl.home (Scott Lurndal) - 2019-10-24 17:22 +0000
Re: Bit field usage Bonita Montero <Bonita.Montero@gmail.com> - 2019-10-24 19:45 +0200
Re: Bit field usage jacobnavia <jacob@jacob.remcomp.fr> - 2019-10-24 19:59 +0200
Re: Bit field usage Bonita Montero <Bonita.Montero@gmail.com> - 2019-10-24 20:02 +0200
Re: Bit field usage Joe Pfeiffer <pfeiffer@cs.nmsu.edu> - 2019-10-24 21:29 -0600
Re: Bit field usage Bonita Montero <Bonita.Montero@gmail.com> - 2019-10-25 07:51 +0200
Re: Bit field usage scott@slp53.sl.home (Scott Lurndal) - 2019-10-25 15:05 +0000
Re: Bit field usage Bart <bc@freeuk.com> - 2019-10-24 19:13 +0100
Re: Bit field usage Bonita Montero <Bonita.Montero@gmail.com> - 2019-10-24 20:54 +0200
Re: Bit field usage Bart <bc@freeuk.com> - 2019-10-24 20:12 +0100
Re: Bit field usage David Brown <david.brown@hesbynett.no> - 2019-10-24 23:03 +0200
Re: Bit field usage Ben Bacarisse <ben.usenet@bsb.me.uk> - 2019-10-24 22:50 +0100
Re: Bit field usage David Brown <david.brown@hesbynett.no> - 2019-10-25 09:18 +0200
Re: Bit field usage Reinhardt Behm <rbehm@hushmail.com> - 2019-10-25 15:46 +0800
Re: Bit field usage Robert Wessel <robertwessel2@yahoo.com> - 2019-10-26 12:36 -0500
Re: Bit field usage scott@slp53.sl.home (Scott Lurndal) - 2019-10-25 15:04 +0000
Re: Bit field usage Robert Wessel <robertwessel2@yahoo.com> - 2019-10-26 12:40 -0500
Re: Bit field usage Philipp Klaus Krause <pkk@spth.de> - 2019-10-26 21:12 +0200
Re: Bit field usage Joe Pfeiffer <pfeiffer@cs.nmsu.edu> - 2019-10-25 09:25 -0600
Re: Bit field usage Robert Wessel <robertwessel2@yahoo.com> - 2019-10-26 12:52 -0500
Re: Bit field usage jacobnavia <jacob@jacob.remcomp.fr> - 2019-10-24 19:56 +0200
Re: Bit field usage already5chosen@yahoo.com - 2019-10-24 12:03 -0700
Re: Bit field usage scott@slp53.sl.home (Scott Lurndal) - 2019-10-24 19:40 +0000
Re: Bit field usage jacobnavia <jacob@jacob.remcomp.fr> - 2019-10-24 22:15 +0200
Re: Bit field usage already5chosen@yahoo.com - 2019-10-24 14:16 -0700
Re: Bit field usage Tim Rentsch <tr.17687@z991.linuxsc.com> - 2019-10-24 17:50 -0700
Re: Bit field usage Joe Pfeiffer <pfeiffer@cs.nmsu.edu> - 2019-10-25 09:36 -0600
Re: Bit field usage Tim Rentsch <tr.17687@z991.linuxsc.com> - 2019-10-27 04:54 -0700
Re: Bit field usage Joe Pfeiffer <pfeiffer@cs.nmsu.edu> - 2019-10-27 10:05 -0600
Re: Bit field usage Philipp Klaus Krause <pkk@spth.de> - 2019-10-26 20:15 +0200
Re: Bit field usage Philipp Klaus Krause <pkk@spth.de> - 2019-10-26 20:16 +0200
Re: Bit field usage jacobnavia <jacob@jacob.remcomp.fr> - 2019-10-26 20:37 +0200
Re: Bit field usage Robert Wessel <robertwessel2@yahoo.com> - 2019-10-26 13:41 -0500
Re: Bit field usage jacobnavia <jacob@jacob.remcomp.fr> - 2019-10-26 21:54 +0200
Re: Bit field usage already5chosen@yahoo.com - 2019-10-27 03:46 -0700
Re: Bit field usage jacobnavia <jacob@jacob.remcomp.fr> - 2019-10-27 12:50 +0100
Re: Bit field usage already5chosen@yahoo.com - 2019-10-27 06:37 -0700
Re: Bit field usage David Brown <david.brown@hesbynett.no> - 2019-10-27 13:00 +0100
Re: Bit field usage already5chosen@yahoo.com - 2019-10-27 07:19 -0700
Re: Bit field usage David Brown <david.brown@hesbynett.no> - 2019-10-27 22:30 +0100
Re: Bit field usage Christopher Collins <ccollins476ad@gmail.com> - 2019-11-07 12:36 -0800
Re: Bit field usage David Brown <david.brown@hesbynett.no> - 2019-11-08 08:18 +0100
Re: Bit field usage Christopher Collins <ccollins476ad@gmail.com> - 2019-11-08 10:19 -0800
Re: Bit field usage Jorgen Grahn <grahn+nntp@snipabacken.se> - 2019-11-08 21:47 +0000
Re: Bit field usage David Brown <david.brown@hesbynett.no> - 2019-11-10 14:08 +0100
Re: Bit field usage Christopher Collins <ccollins476ad@gmail.com> - 2019-11-11 09:26 -0800
Re: Bit field usage David Brown <david.brown@hesbynett.no> - 2019-11-11 20:31 +0100
Re: Bit field usage Christopher Collins <ccollins476ad@gmail.com> - 2019-11-11 23:01 -0800
Re: Bit field usage Christopher Collins <ccollins476ad@gmail.com> - 2019-11-11 23:25 -0800
Re: Bit field usage David Brown <david.brown@hesbynett.no> - 2019-11-12 10:54 +0100
Re: Bit field usage Jorgen Grahn <grahn+nntp@snipabacken.se> - 2019-11-12 14:43 +0000
Re: Bit field usage James Kuyper <jameskuyper@alumni.caltech.edu> - 2019-11-12 10:54 -0500
Re: Bit field usage David Brown <david.brown@hesbynett.no> - 2019-11-12 19:37 +0100
Re: Bit field usage Robert Wessel <robertwessel2@yahoo.com> - 2019-10-27 08:36 -0500
Re: Bit field usage already5chosen@yahoo.com - 2019-10-27 06:49 -0700
Re: Bit field usage Bonita Montero <Bonita.Montero@gmail.com> - 2019-10-27 14:23 +0100
Re: Bit field usage Robert Wessel <robertwessel2@yahoo.com> - 2019-10-27 08:42 -0500
Re: Bit field usage Philipp Klaus Krause <pkk@spth.de> - 2019-10-26 21:06 +0200
Re: Bit field usage Bart <bc@freeuk.com> - 2019-10-26 20:41 +0100
Re: Bit field usage Philipp Klaus Krause <pkk@spth.de> - 2019-10-27 08:29 +0100
Re: Bit field usage David Brown <david.brown@hesbynett.no> - 2019-10-27 13:05 +0100
Page 3 of 4 — ← Prev page 1 2 [3] 4 Next page →
| From | already5chosen@yahoo.com |
|---|---|
| Date | 2019-10-27 06:37 -0700 |
| Message-ID | <ecf96188-d642-4211-a738-ddd98fdaf6bb@googlegroups.com> |
| In reply to | #147281 |
On Sunday, October 27, 2019 at 1:50:57 PM UTC+2, jacobnavia wrote: > Le 27/10/2019 à 11:46, already5chosen@yahoo.com a écrit : > > ARM/ARM64 and POWER. ARM has no alignment requirements on the integer side of the ISA. > > Here are the relevant pages of the ARM64 Architecture manual > > <quote> > B2.4.2 Alignment of data accesses > An unaligned access to any type of Device memory causes an Alignment fault. > The alignment requirements for accesses to Normal memory are as follows: > • For all instructions that load or store a single or multiple > registers, other than Load-Exclusive/Store-Exclusive and > Load-Acquire/Store-Release, if the address that is accessed is not > aligned to the size of the data element being accessed, then one of the > following occurs: > — An Alignment fault is generated. > — An unaligned access is performed. > > SCTLR_ELx.A at the current Exception level can be configured to enable > an alignment check, and thereby determine which of these two options is > used. > Note > — The SCTLR_EL1.A bit that is applicable to software running at EL0, can > only be accessed from EL1 > or above. > — Alignment checks are based on element size, not overall access size. > This affects SIMD element and structure loads and stores, and also > Load/Store pair instructions. > • For all Load-Exclusive/Store-Exclusive and Load-Acquire/Store-Release > memory accesses that access a single element or a pair of elements, an > alignment fault is generated if the address being accessed is not > aligned to the size of the data structure being accessed. > A failed alignment check results in an Alignment fault, which is taken > as a Data Abort exception. These exceptions are taken at the lowest > Exception level that can handle the exception, consistent with the basic > requirement that the Exception level never decreases on an exception. > > B2.4.3 Unaligned data access restrictions > • Accesses are not guaranteed to be single-copy atomic except at the > byte access level. > • Unaligned accesses typically takes a number of additional cycles to > complete compared to a naturally-aligned access. That's part is not true on high-performance ARMv8A cores, like last 4-5 generation of Apple's Axx or Cortex-A76. Typically, i.e. as long as there is no page crossing, the cost of unaligned accesses is at worst the same as o 2 aligned accesses, but often less than that. > • An operation that performs an unaligned access can abort on any memory > access that it makes, and can abort on more than one access. This means > that an unaligned access that occurs across a page boundary can > generate an abort on either side of the boundary. That's not different from x86, except that on x86 it's called 'fault' rather than 'abort'. > </end quote> > > The situation is not really as you describe it. Alignment still is > important for many operations and can't be dismissed. That is why the > compilers will always align the data at its natural boundaries. In practice that's exactly the same as x86-64. On both platforms non-aligned accesses work fine and fast, but not guaranteed to be atomic. ARM's ability to throw exception on non-SIMD unaligned access can be useful for debugging/tuning, but there are no reasons to use it for release builds.
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2019-10-27 13:00 +0100 |
| Message-ID | <qp40s8$pvs$1@dont-email.me> |
| In reply to | #147279 |
On 27/10/2019 11:46, already5chosen@yahoo.com wrote: > On Saturday, October 26, 2019 at 10:54:34 PM UTC+3, jacobnavia > wrote: >> Le 26/10/2019 à 20:41, Robert Wessel a écrit : >>> That is not true of all 64-bit implementations, of course. >>> Consider MSVC invoked with /Zp1. Of course it's true of many >>> implementations. >> >> Yes, packing fields would be possible in processors like the x86. >> It is not possible in RISC processors where alignment is much >> stricter. > > There are only 2 high-performance RISCs that are still relevant for > new development: ARM/ARM64 and POWER. ARM has no alignment > requirements on the integer side of the ISA. The same for Power in > Big Endian mode. As far as I remember, Power operating in Little > Endian mode used to have alignment requirements, but it seems that > since Power8 they have "pure little-endian" mode that removes these > limitations. > There are many, many other RISC ISA's that are in heavy use - the world does /not/ revolve around the fastest cores. And for lots of ISA's, alignment is strict. Even for ISA's that sometimes allow unaligned access, it can often depend on the implementation. Some ARM core implementations support unaligned access, others do not, others support it only for certain instructions. The same applies to PPC (I don't know the details of Power). Almost all ISA's (including x86) fail on unaligned access for certain kinds of accesses - typically atomic or lock instructions, vector instructions, load/store multiple instructions, etc. And for many devices, unaligned access can be very much slower than aligned access.
[toc] | [prev] | [next] | [standalone]
| From | already5chosen@yahoo.com |
|---|---|
| Date | 2019-10-27 07:19 -0700 |
| Message-ID | <95febac6-81a6-490b-9197-36c3b1ae5811@googlegroups.com> |
| In reply to | #147283 |
On Sunday, October 27, 2019 at 2:00:17 PM UTC+2, David Brown wrote: > On 27/10/2019 11:46, already5chosen@yahoo.com wrote: > > On Saturday, October 26, 2019 at 10:54:34 PM UTC+3, jacobnavia > > wrote: > >> Le 26/10/2019 à 20:41, Robert Wessel a écrit : > >>> That is not true of all 64-bit implementations, of course. > >>> Consider MSVC invoked with /Zp1. Of course it's true of many > >>> implementations. > >> > >> Yes, packing fields would be possible in processors like the x86. > >> It is not possible in RISC processors where alignment is much > >> stricter. > > > > There are only 2 high-performance RISCs that are still relevant for > > new development: ARM/ARM64 and POWER. ARM has no alignment > > requirements on the integer side of the ISA. The same for Power in > > Big Endian mode. As far as I remember, Power operating in Little > > Endian mode used to have alignment requirements, but it seems that > > since Power8 they have "pure little-endian" mode that removes these > > limitations. > > > > There are many, many other RISC ISA's that are in heavy use - the world > does /not/ revolve around the fastest cores. And for lots of ISA's, > alignment is strict. > > Even for ISA's that sometimes allow unaligned access, it can often > depend on the implementation. Some ARM core implementations support > unaligned access, others do not, others support it only for certain > instructions. IIRC, under ARMv7 or later support for unaligned accesses is mandatory. Of course, only for "normal' memory, I/O is different and implementation-dependent, as it should be. > The same applies to PPC (I don't know the details of > Power). Almost all ISA's (including x86) fail on unaligned access for > certain kinds of accesses - typically atomic or lock instructions, > vector instructions, load/store multiple instructions, etc. And for > many devices, unaligned access can be very much slower than aligned access. Atomics can't remain atomic, that's obvious. They don't have to fail, but as long as they don't do what they are intended to do it's of little importance. As to vectors, the trend here is certainly toward relaxation or removal of alignment restrictions.
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2019-10-27 22:30 +0100 |
| Message-ID | <qp529j$eep$1@dont-email.me> |
| In reply to | #147291 |
On 27/10/2019 15:19, already5chosen@yahoo.com wrote: > On Sunday, October 27, 2019 at 2:00:17 PM UTC+2, David Brown wrote: >> On 27/10/2019 11:46, already5chosen@yahoo.com wrote: >>> On Saturday, October 26, 2019 at 10:54:34 PM UTC+3, jacobnavia >>> wrote: >>>> Le 26/10/2019 à 20:41, Robert Wessel a écrit : >>>>> That is not true of all 64-bit implementations, of course. >>>>> Consider MSVC invoked with /Zp1. Of course it's true of >>>>> many implementations. >>>> >>>> Yes, packing fields would be possible in processors like the >>>> x86. It is not possible in RISC processors where alignment is >>>> much stricter. >>> >>> There are only 2 high-performance RISCs that are still relevant >>> for new development: ARM/ARM64 and POWER. ARM has no alignment >>> requirements on the integer side of the ISA. The same for Power >>> in Big Endian mode. As far as I remember, Power operating in >>> Little Endian mode used to have alignment requirements, but it >>> seems that since Power8 they have "pure little-endian" mode that >>> removes these limitations. >>> >> >> There are many, many other RISC ISA's that are in heavy use - the >> world does /not/ revolve around the fastest cores. And for lots of >> ISA's, alignment is strict. >> >> Even for ISA's that sometimes allow unaligned access, it can often >> depend on the implementation. Some ARM core implementations >> support unaligned access, others do not, others support it only for >> certain instructions. > > IIRC, under ARMv7 or later support for unaligned accesses is > mandatory. Of course, only for "normal' memory, I/O is different and > implementation-dependent, as it should be. > >> The same applies to PPC (I don't know the details of Power). >> Almost all ISA's (including x86) fail on unaligned access for >> certain kinds of accesses - typically atomic or lock instructions, >> vector instructions, load/store multiple instructions, etc. And >> for many devices, unaligned access can be very much slower than >> aligned access. > > Atomics can't remain atomic, that's obvious. They don't have to fail, > but as long as they don't do what they are intended to do it's of > little importance. As to vectors, the trend here is certainly toward > relaxation or removal of alignment restrictions. > I don't believe there is any such trend towards removing or relaxing alignment restrictions. I can't claim to have followed cpu details closely enough to be confident in that belief, but I certainly don't see any benefit in having that trend. There are rarely any advantages in having non-aligned data, and you usually have to go out of your way to create it in the first place (often invoking undefined behaviour) - while there are good hardware efficiency reasons for wanting alignment. For vector instructions, it is not always clear what is meant by "aligned" access. If you have a vector of 4 4-byte integers, for example, it can be convenient for the programmer if the alignment requirements are 4 byte alignment rather than 16 byte alignment. But there is little to be gained for the programmer by allowing 1 byte alignment access. It seems to me that regardless of whether or not a particular cpu implementation supports unaligned access or not, that it is almost always best to stick to the alignment specified by the ABI and handled automatically by the compiler.
[toc] | [prev] | [next] | [standalone]
| From | Christopher Collins <ccollins476ad@gmail.com> |
|---|---|
| Date | 2019-11-07 12:36 -0800 |
| Message-ID | <slrnqs901k.s72.ccollins476ad@pseudoephedrine.nightmare-heaven.no-ip.biz> |
| In reply to | #147296 |
On 2019-10-27, David Brown <david.brown@hesbynett.no> wrote: > I don't believe there is any such trend towards removing or relaxing > alignment restrictions. I can't claim to have followed cpu details > closely enough to be confident in that belief, but I certainly don't see > any benefit in having that trend. There are rarely any advantages in > having non-aligned data, and you usually have to go out of your way to > create it in the first place (often invoking undefined behaviour) - > while there are good hardware efficiency reasons for wanting alignment. I disagree with the claim that there is rarely any advantage in having unaligned data. Combined with packed structs, support for unaligned access can result in a considerable code size reduction. I included a simple demonstration in an earlier post: <https://groups.google.com/d/msg/comp.lang.c++/a5xVfaw1y08/IdcvfGNbFQAJ>. Chris
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2019-11-08 08:18 +0100 |
| Message-ID | <qq34rd$v8u$1@dont-email.me> |
| In reply to | #147747 |
On 07/11/2019 21:36, Christopher Collins wrote: > On 2019-10-27, David Brown <david.brown@hesbynett.no> wrote: >> I don't believe there is any such trend towards removing or relaxing >> alignment restrictions. I can't claim to have followed cpu details >> closely enough to be confident in that belief, but I certainly don't see >> any benefit in having that trend. There are rarely any advantages in >> having non-aligned data, and you usually have to go out of your way to >> create it in the first place (often invoking undefined behaviour) - >> while there are good hardware efficiency reasons for wanting alignment. > > I disagree with the claim that there is rarely any advantage in having > unaligned data. Combined with packed structs, support for unaligned > access can result in a considerable code size reduction. I included a > simple demonstration in an earlier post: > <https://groups.google.com/d/msg/comp.lang.c++/a5xVfaw1y08/IdcvfGNbFQAJ>. > I don't remember the details of that thread, but it looks like you are trying to find an efficient way to copy a packed struct into a byte buffer. The quotation from my own post was: > Write your code properly and safely (using shifts and masks, memcpy, or > compiler-specific features or intrinsics) and let the compiler turn it > into unaligned accesses. Writing safe, correct, and valid source code > is the programmer's responsibility. Turning it into small and fast > object code is the compiler's responsibility. Don't try to do the > compiler's job - work with it so that it can to the best job it can. I stand by that advice. By using the compiler-specific "packed" struct feature (most compilers have an equivalent, but the details are specific to the compiler) it is then safe to use a "memcpy" for a short marshal function. And if you also use the "align" attribute (or C11 _Alignas), the compiler can do the copying using aligned 32 bit accesses rather than unaligned accesses, for greater speed. Unaligned accesses are not a benefit here - aligned would have worked better.
[toc] | [prev] | [next] | [standalone]
| From | Christopher Collins <ccollins476ad@gmail.com> |
|---|---|
| Date | 2019-11-08 10:19 -0800 |
| Message-ID | <slrnqsbcdc.s72.ccollins476ad@pseudoephedrine.nightmare-heaven.no-ip.biz> |
| In reply to | #147759 |
On 2019-11-08, David Brown <david.brown@hesbynett.no> wrote: > On 07/11/2019 21:36, Christopher Collins wrote: >> I disagree with the claim that there is rarely any advantage in having >> unaligned data. Combined with packed structs, support for unaligned >> access can result in a considerable code size reduction. I included a >> simple demonstration in an earlier post: >> <https://groups.google.com/d/msg/comp.lang.c++/a5xVfaw1y08/IdcvfGNbFQAJ>. >> > > I don't remember the details of that thread, but it looks like you are > trying to find an efficient way to copy a packed struct into a byte > buffer. The quotation from my own post was: > > > Write your code properly and safely (using shifts and masks, memcpy, or > > compiler-specific features or intrinsics) and let the compiler turn it > > into unaligned accesses. Writing safe, correct, and valid source code > > is the programmer's responsibility. Turning it into small and fast > > object code is the compiler's responsibility. Don't try to do the > > compiler's job - work with it so that it can to the best job it can. > > I stand by that advice. By using the compiler-specific "packed" struct > feature (most compilers have an equivalent, but the details are specific > to the compiler) it is then safe to use a "memcpy" for a short marshal > function. And if you also use the "align" attribute (or C11 _Alignas), > the compiler can do the copying using aligned 32 bit accesses rather > than unaligned accesses, for greater speed. > > Unaligned accesses are not a benefit here - aligned would have worked > better. You can't always arrange for aligned data. Take a networking stack for example. You need functions to parse and strip headers from the front of a buffer. Unless each header is sized according to the alignment requirements of the processor, the buffer won't remain aligned throughout this process. The reverse process, prepending headers to outgoing data, has the same characteristics. I used to eschew packed structs as nonstandard and of little practical use. Then we tried using them in a Bluetooth stack implementation and the reduction in code size was dramatic (sorry, I don't have numbers). I believe there is simply no way to achieve the same reduction in code size without using packed structs (on architectures that support unaligned access). Chris
[toc] | [prev] | [next] | [standalone]
| From | Jorgen Grahn <grahn+nntp@snipabacken.se> |
|---|---|
| Date | 2019-11-08 21:47 +0000 |
| Message-ID | <slrnqsbojj.cdo.grahn+nntp@frailea.sa.invalid> |
| In reply to | #147793 |
On Fri, 2019-11-08, Christopher Collins wrote: > On 2019-11-08, David Brown <david.brown@hesbynett.no> wrote: >> On 07/11/2019 21:36, Christopher Collins wrote: >>> I disagree with the claim that there is rarely any advantage in having >>> unaligned data. Combined with packed structs, support for unaligned >>> access can result in a considerable code size reduction. I included a >>> simple demonstration in an earlier post: >>> <https://groups.google.com/d/msg/comp.lang.c++/a5xVfaw1y08/IdcvfGNbFQAJ>. >>> >> >> I don't remember the details of that thread, but it looks like you are >> trying to find an efficient way to copy a packed struct into a byte >> buffer. The quotation from my own post was: >> >> > Write your code properly and safely (using shifts and masks, memcpy, or >> > compiler-specific features or intrinsics) and let the compiler turn it >> > into unaligned accesses. Writing safe, correct, and valid source code >> > is the programmer's responsibility. Turning it into small and fast >> > object code is the compiler's responsibility. Don't try to do the >> > compiler's job - work with it so that it can to the best job it can. >> >> I stand by that advice. By using the compiler-specific "packed" struct >> feature (most compilers have an equivalent, but the details are specific >> to the compiler) it is then safe to use a "memcpy" for a short marshal >> function. And if you also use the "align" attribute (or C11 _Alignas), >> the compiler can do the copying using aligned 32 bit accesses rather >> than unaligned accesses, for greater speed. >> >> Unaligned accesses are not a benefit here - aligned would have worked >> better. > > You can't always arrange for aligned data. Take a networking stack for > example. You need functions to parse and strip headers from the front > of a buffer. Unless each header is sized according to the alignment > requirements of the processor, the buffer won't remain aligned > throughout this process. > > The reverse process, prepending headers to outgoing data, has the same > characteristics. > > I used to eschew packed structs as nonstandard and of little practical > use. Then we tried using them in a Bluetooth stack implementation and > the reduction in code size was dramatic (sorry, I don't have numbers). I find that hard to believe: few programs have an infinite number of data structures to (de)serialise, and the code for each would be quite small. The code size is proportional to the size of the protocol specification. Or rather: I don't find it hard to believe that using packed structs can result in less object code, I just find it hard to believe it often matters. Maybe you had a tiny budget for program memory? I don't do tiny embedded systems much, and don't worry about, say, a few dozen kilobytes extra. Or maybe excessive inlining (like gcc -O3) inflated the numbers? > I believe there is simply no way to achieve the same reduction in code > size without using packed structs (on architectures that support > unaligned access). > > Chris /Jorgen -- // Jorgen Grahn <grahn@ Oo o. . . \X/ snipabacken.se> O o .
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2019-11-10 14:08 +0100 |
| Message-ID | <qq9251$aej$1@dont-email.me> |
| In reply to | #147793 |
On 08/11/2019 19:19, Christopher Collins wrote: > On 2019-11-08, David Brown <david.brown@hesbynett.no> wrote: >> On 07/11/2019 21:36, Christopher Collins wrote: >>> I disagree with the claim that there is rarely any advantage in having >>> unaligned data. Combined with packed structs, support for unaligned >>> access can result in a considerable code size reduction. I included a >>> simple demonstration in an earlier post: >>> <https://groups.google.com/d/msg/comp.lang.c++/a5xVfaw1y08/IdcvfGNbFQAJ>. >>> >> >> I don't remember the details of that thread, but it looks like you are >> trying to find an efficient way to copy a packed struct into a byte >> buffer. The quotation from my own post was: >> >>> Write your code properly and safely (using shifts and masks, memcpy, or >>> compiler-specific features or intrinsics) and let the compiler turn it >>> into unaligned accesses. Writing safe, correct, and valid source code >>> is the programmer's responsibility. Turning it into small and fast >>> object code is the compiler's responsibility. Don't try to do the >>> compiler's job - work with it so that it can to the best job it can. >> >> I stand by that advice. By using the compiler-specific "packed" struct >> feature (most compilers have an equivalent, but the details are specific >> to the compiler) it is then safe to use a "memcpy" for a short marshal >> function. And if you also use the "align" attribute (or C11 _Alignas), >> the compiler can do the copying using aligned 32 bit accesses rather >> than unaligned accesses, for greater speed. >> >> Unaligned accesses are not a benefit here - aligned would have worked >> better. > > You can't always arrange for aligned data. Take a networking stack for > example. You need functions to parse and strip headers from the front > of a buffer. Unless each header is sized according to the alignment > requirements of the processor, the buffer won't remain aligned > throughout this process. > > The reverse process, prepending headers to outgoing data, has the same > characteristics. I said that unaligned accesses were not a benefit in this case, not that they are never useful. > > I used to eschew packed structs as nonstandard and of little practical > use. Then we tried using them in a Bluetooth stack implementation and > the reduction in code size was dramatic (sorry, I don't have numbers). > I believe there is simply no way to achieve the same reduction in code > size without using packed structs (on architectures that support > unaligned access). > You are wrong - but only if you have a good enough compiler, use the right options, and write your code in a way that the compiler recognises and optimises. It is entirely possible for a compiler to optimise memcpy or byte-by-byte access into unaligned word access if the target supports it, and it certainly happens in some cases. But it won't happen in all cases, and if efficiency matters you'll have to check the generated output. I don't see much use of packed structs. But that does not mean they are not useful on occasion.
[toc] | [prev] | [next] | [standalone]
| From | Christopher Collins <ccollins476ad@gmail.com> |
|---|---|
| Date | 2019-11-11 09:26 -0800 |
| Message-ID | <slrnqsj6dd.ih3.ccollins476ad@pseudoephedrine.nightmare-heaven.no-ip.biz> |
| In reply to | #147875 |
On 2019-11-10, David Brown <david.brown@hesbynett.no> wrote:
> On 08/11/2019 19:19, Christopher Collins wrote:
>> You can't always arrange for aligned data. Take a networking stack for
>> example. You need functions to parse and strip headers from the front
>> of a buffer. Unless each header is sized according to the alignment
>> requirements of the processor, the buffer won't remain aligned
>> throughout this process.
>>
>> The reverse process, prepending headers to outgoing data, has the same
>> characteristics.
>
> I said that unaligned accesses were not a benefit in this case, not that
> they are never useful.
This is what you said:
There are rarely any advantages in having non-aligned data, and you
usually have to go out of your way to create it in the first place
(often invoking undefined behaviour) - while there are good hardware
efficiency reasons for wanting alignment.
To me, this sounds like you object to using unaligned data except in
very special circumstances. I disagree, but perhaps I am misreading
your argument.
>> I used to eschew packed structs as nonstandard and of little practical
>> use. Then we tried using them in a Bluetooth stack implementation and
>> the reduction in code size was dramatic (sorry, I don't have numbers).
>> I believe there is simply no way to achieve the same reduction in code
>> size without using packed structs (on architectures that support
>> unaligned access).
>>
>
> You are wrong - but only if you have a good enough compiler, use the
> right options, and write your code in a way that the compiler recognises
> and optimises. It is entirely possible for a compiler to optimise
> memcpy or byte-by-byte access into unaligned word access if the target
> supports it, and it certainly happens in some cases. But it won't
> happen in all cases, and if efficiency matters you'll have to check the
> generated output.
Do you know of a compiler that does that? (Honest question). From the
godbolt example I posted, it seems gcc with -Os does not. In theory,
compilers could do all sorts of optimizations. That doesn't help
someone meet a project's requirements.
> I don't see much use of packed structs. But that does not mean they are
> not useful on occasion.
In addition to reduced code size, packed structs also simplify code.
Rather than needing to implement unmarshalling code for every header and
command in a stack, you simply do this:
struct foo_header *hdr = (struct foo_header *)buf;
and you have a header ready to be processed.
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2019-11-11 20:31 +0100 |
| Message-ID | <qqccum$lt5$1@dont-email.me> |
| In reply to | #147940 |
On 11/11/2019 18:26, Christopher Collins wrote:
> On 2019-11-10, David Brown <david.brown@hesbynett.no> wrote:
>> On 08/11/2019 19:19, Christopher Collins wrote:
>>> You can't always arrange for aligned data. Take a networking stack for
>>> example. You need functions to parse and strip headers from the front
>>> of a buffer. Unless each header is sized according to the alignment
>>> requirements of the processor, the buffer won't remain aligned
>>> throughout this process.
>>>
>>> The reverse process, prepending headers to outgoing data, has the same
>>> characteristics.
>>
>> I said that unaligned accesses were not a benefit in this case, not that
>> they are never useful.
>
> This is what you said:
>
> There are rarely any advantages in having non-aligned data, and you
> usually have to go out of your way to create it in the first place
> (often invoking undefined behaviour) - while there are good hardware
> efficiency reasons for wanting alignment.
>
> To me, this sounds like you object to using unaligned data except in
> very special circumstances. I disagree, but perhaps I am misreading
> your argument.
No, that is a reasonable summary of what I said. There /are/ times when
unaligned accesses are the best solution (noting that "best" depends on
the requirements, and can be very subjective) - but I don't think it
happens often. And even then, I think it is better to let the compiler
deal with it rather than manually accessing data at non-aligned
addresses. It's fine if the compiler turns a memcpy() of 4 bytes into a
single word read - much less fine if the programmer casts a char* or
void* pointer to an int* in order to access the non-aligned data.
Similarly, /sometimes/ packed structs are a convenient solution - but
not often.
>
>>> I used to eschew packed structs as nonstandard and of little practical
>>> use. Then we tried using them in a Bluetooth stack implementation and
>>> the reduction in code size was dramatic (sorry, I don't have numbers).
>>> I believe there is simply no way to achieve the same reduction in code
>>> size without using packed structs (on architectures that support
>>> unaligned access).
>>>
>>
>> You are wrong - but only if you have a good enough compiler, use the
>> right options, and write your code in a way that the compiler recognises
>> and optimises. It is entirely possible for a compiler to optimise
>> memcpy or byte-by-byte access into unaligned word access if the target
>> supports it, and it certainly happens in some cases. But it won't
>> happen in all cases, and if efficiency matters you'll have to check the
>> generated output.
>
> Do you know of a compiler that does that? (Honest question). From the
> godbolt example I posted, it seems gcc with -Os does not. In theory,
> compilers could do all sorts of optimizations. That doesn't help
> someone meet a project's requirements.
From the example you posted, gcc /does/ do exactly that. You wrote
"memcpy(&out[1], &m->b, 4);", and the compiler generated "ldr r3, [r0,
#1]" "str r3, [r1, #1]".
When you already have the packed struct, it makes more sense to do a
single memcpy() rather than several individual memcpy's turned into
unaligned accesses. But the compiler is clearly optimising the memcpy's
into larger (potentially) unaligned accesses.
>
>> I don't see much use of packed structs. But that does not mean they are
>> not useful on occasion.
>
> In addition to reduced code size, packed structs also simplify code.
Your code was not really doing marshalling, despite the name of the
functions, since it was just a straight copy.
Usually when you are reading in the header for data coming in from
outside (on the network, or in a file), you are doing lots of work on it
anyway - checking for validity, in particular. And usually much of the
header will be used only at that point. You often don't need to store
it, and you don't need to access the fields.
But sure, on the occasions when packed structs really help, use them.
> Rather than needing to implement unmarshalling code for every header and
> command in a stack, you simply do this:
>
> struct foo_header *hdr = (struct foo_header *)buf;
>
> and you have a header ready to be processed.
>
Except that you don't - you have to be careful with casting pointer
types, or fall foul of aliasing rules. If you are doing a lot of this
kind of thing, you might like to add:
#pragma GCC optimize("-fno-strict-aliasing")
and then the cast is safe (on gcc or clang).
[toc] | [prev] | [next] | [standalone]
| From | Christopher Collins <ccollins476ad@gmail.com> |
|---|---|
| Date | 2019-11-11 23:01 -0800 |
| Message-ID | <slrnqskm5n.ih3.ccollins476ad@pseudoephedrine.nightmare-heaven.no-ip.biz> |
| In reply to | #147944 |
On 2019-11-11, David Brown <david.brown@hesbynett.no> wrote:
> On 11/11/2019 18:26, Christopher Collins wrote:
>> Rather than needing to implement unmarshalling code for every header and
>> command in a stack, you simply do this:
>>
>> struct foo_header *hdr = (struct foo_header *)buf;
>>
>> and you have a header ready to be processed.
>>
>
> Except that you don't - you have to be careful with casting pointer
> types, or fall foul of aliasing rules. If you are doing a lot of this
> kind of thing, you might like to add:
>
> #pragma GCC optimize("-fno-strict-aliasing")
>
> and then the cast is safe (on gcc or clang).
I'm not sure that's true, but I'll admit that I'm not terribly familiar
with the C spec. I tried this test with gcc 9.2.0:
$ cat aliasing.c
struct s {
char c;
int i;
};
void dosomething(struct s *s);
int main(void) {
unsigned char cbuf[100] = { 0 };
float fbuf[100] = { 0 };
struct s *s0 = (struct s *)(cbuf + 7);
struct s *s1 = (struct s *)(fbuf + 7);
dosomething(s0);
dosomething(s1);
}
$ gcc -O2 -Wall -fstrict-aliasing -Wstrict-aliasing=1 -pedantic-errors aliasing.c
aliasing.c: In function 'main':
aliasing.c:11:38: warning: dereferencing type-punned pointer might break strict-aliasing rules [-Wstrict-aliasing]
11 | struct s s1 = *(struct s *)(fbuf + 7);
| ~~~~~~^~~~
(plus a linker error due to `dosomething` being undefined)
It warns about the float array, not the unsigned char. If casting a
char buffer to a pointer-to-struct is undefined without an additional
attribute or compiler option then that would be good to know.
In any case, I feel like I've said my piece as best I could.
Chris
[toc] | [prev] | [next] | [standalone]
| From | Christopher Collins <ccollins476ad@gmail.com> |
|---|---|
| Date | 2019-11-11 23:25 -0800 |
| Message-ID | <slrnqsknid.ih3.ccollins476ad@pseudoephedrine.nightmare-heaven.no-ip.biz> |
| In reply to | #147947 |
On 2019-11-12, Christopher Collins <ccollins476ad@gmail.com> wrote:
> On 2019-11-11, David Brown <david.brown@hesbynett.no> wrote:
>> On 11/11/2019 18:26, Christopher Collins wrote:
>>> Rather than needing to implement unmarshalling code for every header and
>>> command in a stack, you simply do this:
>>>
>>> struct foo_header *hdr = (struct foo_header *)buf;
>>>
>>> and you have a header ready to be processed.
>>>
>>
>> Except that you don't - you have to be careful with casting pointer
>> types, or fall foul of aliasing rules. If you are doing a lot of this
>> kind of thing, you might like to add:
>>
>> #pragma GCC optimize("-fno-strict-aliasing")
>>
>> and then the cast is safe (on gcc or clang).
>
> I'm not sure that's true, but I'll admit that I'm not terribly familiar
> with the C spec. I tried this test with gcc 9.2.0:
>
> $ cat aliasing.c
> struct s {
> char c;
> int i;
> };
>
> void dosomething(struct s *s);
>
> int main(void) {
> unsigned char cbuf[100] = { 0 };
> float fbuf[100] = { 0 };
>
> struct s *s0 = (struct s *)(cbuf + 7);
> struct s *s1 = (struct s *)(fbuf + 7);
>
> dosomething(s0);
> dosomething(s1);
> }
>
> $ gcc -O2 -Wall -fstrict-aliasing -Wstrict-aliasing=1 -pedantic-errors aliasing.c
> aliasing.c: In function 'main':
> aliasing.c:11:38: warning: dereferencing type-punned pointer might break strict-aliasing rules [-Wstrict-aliasing]
> 11 | struct s s1 = *(struct s *)(fbuf + 7);
> | ~~~~~~^~~~
>
> (plus a linker error due to `dosomething` being undefined)
>
> It warns about the float array, not the unsigned char. If casting a
> char buffer to a pointer-to-struct is undefined without an additional
> attribute or compiler option then that would be good to know.
Let me just correct myself: I am quite sure both casts indeed violate
the effective type rules. I began that post trying to demonstrate one
thing and ended in a weird place with little understanding of how I got
there! I think that `-Wstring-aliasing` option is just not very
reliable and I let myself be convinced of some things I know aren't
true.
I really just wanted to demonstrate that gcc will always let a
pointer-to-packed-struct alias a character buffer. I have always
assumed this is the case because it has always "worked", but I can't
find this guarantee documented anywhere so perhaps I've just gotten
lucky.
> In any case, I feel like I've said my piece as best I could.
>
> Chris
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2019-11-12 10:54 +0100 |
| Message-ID | <qqdvg7$n95$1@dont-email.me> |
| In reply to | #147947 |
On 12/11/2019 08:01, Christopher Collins wrote:
> On 2019-11-11, David Brown <david.brown@hesbynett.no> wrote:
>> On 11/11/2019 18:26, Christopher Collins wrote:
>>> Rather than needing to implement unmarshalling code for every header and
>>> command in a stack, you simply do this:
>>>
>>> struct foo_header *hdr = (struct foo_header *)buf;
>>>
>>> and you have a header ready to be processed.
>>>
>>
>> Except that you don't - you have to be careful with casting pointer
>> types, or fall foul of aliasing rules. If you are doing a lot of this
>> kind of thing, you might like to add:
>>
>> #pragma GCC optimize("-fno-strict-aliasing")
>>
>> and then the cast is safe (on gcc or clang).
>
> I'm not sure that's true, but I'll admit that I'm not terribly familiar
> with the C spec. I tried this test with gcc 9.2.0:
>
> $ cat aliasing.c
> struct s {
> char c;
> int i;
> };
>
> void dosomething(struct s *s);
>
> int main(void) {
> unsigned char cbuf[100] = { 0 };
> float fbuf[100] = { 0 };
>
> struct s *s0 = (struct s *)(cbuf + 7);
> struct s *s1 = (struct s *)(fbuf + 7);
>
> dosomething(s0);
> dosomething(s1);
> }
>
> $ gcc -O2 -Wall -fstrict-aliasing -Wstrict-aliasing=1 -pedantic-errors aliasing.c
> aliasing.c: In function 'main':
> aliasing.c:11:38: warning: dereferencing type-punned pointer might break strict-aliasing rules [-Wstrict-aliasing]
> 11 | struct s s1 = *(struct s *)(fbuf + 7);
> | ~~~~~~^~~~
>
> (plus a linker error due to `dosomething` being undefined)
>
> It warns about the float array, not the unsigned char. If casting a
> char buffer to a pointer-to-struct is undefined without an additional
> attribute or compiler option then that would be good to know.
>
> In any case, I feel like I've said my piece as best I could.
>
> Chris
>
"-fstrict-aliasing", which is enable with optimisation unless you have
"-fno-strict-aliasing", does not mean that code that messes with pointer
types contrary to 6.5p7 will not work. It merely means that they might
not work - there are no guarantees. Whether the code will work or not
will depend on the optimisation opportunities seen and used by the compiler.
The warnings, usually from "-Wstrict-aliasing=3" (the default if
-fstrict-aliasing and -Wall are in effect - "-Wstrict-aliasing=1" is
less accurate), are supposed to be shown if the compiler has taken
advantage of type-based aliasing for optimisation, and generated code
that is different than you would get if C allowed access to data via any
lvalue type.
[toc] | [prev] | [next] | [standalone]
| From | Jorgen Grahn <grahn+nntp@snipabacken.se> |
|---|---|
| Date | 2019-11-12 14:43 +0000 |
| Message-ID | <slrnqslh8j.cdo.grahn+nntp@frailea.sa.invalid> |
| In reply to | #147949 |
On Tue, 2019-11-12, David Brown wrote:
> On 12/11/2019 08:01, Christopher Collins wrote:
>> On 2019-11-11, David Brown <david.brown@hesbynett.no> wrote:
>>> On 11/11/2019 18:26, Christopher Collins wrote:
>>>> Rather than needing to implement unmarshalling code for every header and
>>>> command in a stack, you simply do this:
>>>>
>>>> struct foo_header *hdr = (struct foo_header *)buf;
>>>>
>>>> and you have a header ready to be processed.
>>>>
>>>
>>> Except that you don't - you have to be careful with casting pointer
>>> types, or fall foul of aliasing rules. If you are doing a lot of this
>>> kind of thing, you might like to add:
>>>
>>> #pragma GCC optimize("-fno-strict-aliasing")
>>>
>>> and then the cast is safe (on gcc or clang).
>>
>> I'm not sure that's true, but I'll admit that I'm not terribly familiar
>> with the C spec. I tried this test with gcc 9.2.0:
>>
>> $ cat aliasing.c
>> struct s {
>> char c;
>> int i;
>> };
>>
>> void dosomething(struct s *s);
>>
>> int main(void) {
>> unsigned char cbuf[100] = { 0 };
>> float fbuf[100] = { 0 };
>>
>> struct s *s0 = (struct s *)(cbuf + 7);
>> struct s *s1 = (struct s *)(fbuf + 7);
>>
>> dosomething(s0);
>> dosomething(s1);
>> }
>>
>> $ gcc -O2 -Wall -fstrict-aliasing -Wstrict-aliasing=1 -pedantic-errors aliasing.c
>> aliasing.c: In function 'main':
>> aliasing.c:11:38: warning: dereferencing type-punned pointer might break strict-aliasing rules [-Wstrict-aliasing]
>> 11 | struct s s1 = *(struct s *)(fbuf + 7);
>> | ~~~~~~^~~~
>>
>> (plus a linker error due to `dosomething` being undefined)
>>
>> It warns about the float array, not the unsigned char. If casting a
>> char buffer to a pointer-to-struct is undefined without an additional
>> attribute or compiler option then that would be good to know.
>>
>> In any case, I feel like I've said my piece as best I could.
>>
>> Chris
>>
>
> "-fstrict-aliasing", which is enable with optimisation unless you have
> "-fno-strict-aliasing", does not mean that code that messes with pointer
> types contrary to 6.5p7 will not work. It merely means that they might
> not work - there are no guarantees. Whether the code will work or not
> will depend on the optimisation opportunities seen and used by the compiler.
>
> The warnings, usually from "-Wstrict-aliasing=3" (the default if
> -fstrict-aliasing and -Wall are in effect - "-Wstrict-aliasing=1" is
> less accurate), are supposed to be shown if the compiler has taken
> advantage of type-based aliasing for optimisation, and generated code
> that is different than you would get if C allowed access to data via any
> lvalue type.
Aren't there special language rules so that it's ok to alias when one
of the types is char or unsigned char? Or maybe I'm confusing this
with something else (I don't do struct mapping myself, unless paid to).
/Jorgen
--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@alumni.caltech.edu> |
|---|---|
| Date | 2019-11-12 10:54 -0500 |
| Message-ID | <qqekji$k16$1@dont-email.me> |
| In reply to | #147952 |
On 11/12/19 9:43 AM, Jorgen Grahn wrote: ... > Aren't there special language rules so that it's ok to alias when one > of the types is char or unsigned char? Or maybe I'm confusing this > with something else (I don't do struct mapping myself, unless paid to). Not quite; not all of the anti-aliasing rules are symmetrical. In some of the rules, the effective type plays a different role than the type of the lvalue used to access it: "An object shall have its stored value accessed only by an lvalue expression that has one of the following types: 88) — a type compatible with the effective type of the object, — a qualified version of a type compatible with the effective type of the object, — a type that is the signed or unsigned type corresponding to the effective type of the object, — a type that is the signed or unsigned type corresponding to a qualified version of the effective type of the object, — an aggregate or union type that includes one of the aforementioned types among its members (including, recursively, a member of a subaggregate or contained union), or — a character type." (6.5p7) Therefore, an object with any effective type can be accessed using an lvalue of character type, but the reverse is not true. When the effective type is a character type, there's examples of types that fit each of the options listed in 6.5p7, but there's also many types that don't fit any of them. For instant, "short int". Similarly, you can alias an object which has an effective type that is an aggregate or union type, using an lvalue of the type of one of it's members. However, if the effective type of an object is type of one of it's members, you cannot, in general, access it using an lvalue of that aggregate or union type.
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2019-11-12 19:37 +0100 |
| Message-ID | <qqeu4v$l3l$1@dont-email.me> |
| In reply to | #147956 |
On 12/11/2019 16:54, James Kuyper wrote: > On 11/12/19 9:43 AM, Jorgen Grahn wrote: > ... >> Aren't there special language rules so that it's ok to alias when one >> of the types is char or unsigned char? Or maybe I'm confusing this >> with something else (I don't do struct mapping myself, unless paid to). > > Not quite; not all of the anti-aliasing rules are symmetrical. In some > of the rules, the effective type plays a different role than the type of > the lvalue used to access it: > > "An object shall have its stored value accessed only by an lvalue > expression that has one of the following types: 88) > — a type compatible with the effective type of the object, > — a qualified version of a type compatible with the effective type of > the object, > — a type that is the signed or unsigned type corresponding to the > effective type of the object, > — a type that is the signed or unsigned type corresponding to a > qualified version of the effective type of the object, > — an aggregate or union type that includes one of the aforementioned > types among its members (including, recursively, a member of a > subaggregate or contained union), or > — a character type." > (6.5p7) > > Therefore, an object with any effective type can be accessed using an > lvalue of character type, but the reverse is not true. When the > effective type is a character type, there's examples of types that fit > each of the options listed in 6.5p7, but there's also many types that > don't fit any of them. For instant, "short int". > > Similarly, you can alias an object which has an effective type that is > an aggregate or union type, using an lvalue of the type of one of it's > members. However, if the effective type of an object is type of one of > it's members, you cannot, in general, access it using an lvalue of that > aggregate or union type. > The other thing that might play a part here are the rules for changing the effective type for "an object having no declared type". As far as I know, that can only actually apply to memory returned by malloc() and friends. However, if the compiler is dealing with a function that receives a pointer via a parameter, it usually can't know if it pointed to "an object having no declared type" or something with a declared type (like a statically allocated or local object). This means that compilers will often assume that it is okay to store data and read data via the pointer, because it often /is/ okay to do so. The point at which compilers are more likely to make use of type-based aliasing, and thus give you warnings about problems, would be if the function tried to access the memory as two different types at the same time. In this case, it would be storing floats in the "fbuf" array, using the array as though it were an array of "struct s", and then expected to be able to access the original floats again.
[toc] | [prev] | [next] | [standalone]
| From | Robert Wessel <robertwessel2@yahoo.com> |
|---|---|
| Date | 2019-10-27 08:36 -0500 |
| Message-ID | <d17bre98fcucvqu9hgb1ivgj39es3iqfvo@4ax.com> |
| In reply to | #147279 |
On Sun, 27 Oct 2019 03:46:42 -0700 (PDT), already5chosen@yahoo.com wrote: >On Saturday, October 26, 2019 at 10:54:34 PM UTC+3, jacobnavia wrote: >> Le 26/10/2019 à 20:41, Robert Wessel a écrit : >> > That is not true of all 64-bit implementations, of course. Consider >> > MSVC invoked with /Zp1. Of course it's true of many implementations. >> >> Yes, packing fields would be possible in processors like the x86. It is >> not possible in RISC processors where alignment is much stricter. > >There are only 2 high-performance RISCs that are still relevant for new development: ARM/ARM64 and POWER. ARM has no alignment requirements on the integer side of the ISA. The same for Power in Big Endian mode. As far as I remember, Power operating in Little Endian mode used to have alignment requirements, but it seems that since Power8 they have "pure little-endian" mode that removes these limitations. AFAIK, POWER always allows non-aligned "normal*" accesses that don't cross page boundaries. The ISA definitions allow the hardware to perform page-crossing unaligned accesses in some circumstances**, but it's not required. Typically the OS will do the usual trap-and-fixup thing. If they've strengthened that guarantee recently, I've missed it. *Restrictions on some types of accesses, of course. **More or less, the (page table) attributes of both pages need to be the same.
[toc] | [prev] | [next] | [standalone]
| From | already5chosen@yahoo.com |
|---|---|
| Date | 2019-10-27 06:49 -0700 |
| Message-ID | <ee581b7b-60bd-4420-8934-fb5f6808990a@googlegroups.com> |
| In reply to | #147287 |
On Sunday, October 27, 2019 at 3:36:16 PM UTC+2, robert...@yahoo.com wrote: > On Sun, 27 Oct 2019 03:46:42 -0700 (PDT), already5chosen@yahoo.com > wrote: > > >On Saturday, October 26, 2019 at 10:54:34 PM UTC+3, jacobnavia wrote: > >> Le 26/10/2019 à 20:41, Robert Wessel a écrit : > >> > That is not true of all 64-bit implementations, of course. Consider > >> > MSVC invoked with /Zp1. Of course it's true of many implementations. > >> > >> Yes, packing fields would be possible in processors like the x86. It is > >> not possible in RISC processors where alignment is much stricter. > > > >There are only 2 high-performance RISCs that are still relevant for new development: ARM/ARM64 and POWER. ARM has no alignment requirements on the integer side of the ISA. The same for Power in Big Endian mode. As far as I remember, Power operating in Little Endian mode used to have alignment requirements, but it seems that since Power8 they have "pure little-endian" mode that removes these limitations. > > > AFAIK, POWER always allows non-aligned "normal*" accesses that don't > cross page boundaries. The ISA definitions allow the hardware to > perform page-crossing unaligned accesses in some circumstances**, but > it's not required. Typically the OS will do the usual trap-and-fixup > thing. > > If they've strengthened that guarantee recently, I've missed it. > Considering that today new POWER/PPC cores are coming only from IBM and that behavior of old cores is not going to change, POWER ISA guaranties are less important than how they were back when the field was more diverse. Implementations are what matters. > > *Restrictions on some types of accesses, of course. > > **More or less, the (page table) attributes of both pages need to be > the same.
[toc] | [prev] | [next] | [standalone]
| From | Bonita Montero <Bonita.Montero@gmail.com> |
|---|---|
| Date | 2019-10-27 14:23 +0100 |
| Message-ID | <qp45p0$6ka$1@news.albasani.net> |
| In reply to | #147261 |
> Yes, packing fields would be possible in processors like the x86. It is > not possible in RISC processors where alignment is much stricter. And > even in the x86 you get a penalty for misaligned pointer data. You can have bit-fields with any architecture.
[toc] | [prev] | [next] | [standalone]
Page 3 of 4 — ← Prev page 1 2 [3] 4 Next page →
Back to top | Article view | comp.lang.c
csiph-web