- Performance of unaligned memory-accesses - 22 Updates
- [announcement] Fast C++ JSON/RJSON parser - 1 Update
- Tricky! - 2 Updates
James Kuyper <jameskuyper@alumni.caltech.edu>: Aug 10 07:31PM -0400 On 8/10/19 5:46 PM, David Brown wrote: > I already did. > These are from N1570, draft of C11 standard - C++ inherits this from C > and the C standards are simpler. Actually, no. C++ cross-references the C standard for many purposes. For instance, it has no description of it's own for virtually the entire C standard library, incorporating it into the C++ standard library almost entirely by reference. However, most features in C++ are explicitly stated in the C++ standard, even when their content is exactly the same as clauses in the C standard. Here's what the C++ standard says about alignment: "Object types have alignment requirements (6.9.1, 6.9.2) which place restrictions on the addresses at which an object of that type may be allocated. An alignment is an implementation-defined integer value representing the number of bytes between successive addresses at which a given object can be allocated. An object type imposes an alignment requirement on every object of that type; stricter alignment can be requested using the alignment specifier (10.6.2)." (6.11p1) Pointer conversions are covered by "If the original pointer value represents the address A of a byte in memory and A does not satisfy the alignment requirement of T, then the resulting pointer value is unspecified." (8.2.9p13) While 8.2.9p13 is specifically about static_cast<>, no other way of converting pointers even addresses performing such pointer conversions, except insofar as the behavior of reinterpret_cast<> is defined in terms of corresponding static_cast<> conversions (8.2.10p7). Trying to use any other method of performing such a conversion has undefined behavior because the "Standard omits any explicit definition of the behavior..." (3.27). |
James Kuyper <jameskuyper@alumni.caltech.edu>: Aug 10 04:37PM -0700 On Saturday, August 10, 2019 at 11:21:30 AM UTC-4, Bonita Montero wrote: > > More importantly here, it also does not mean you can take pointers > > to the unaligned members and use them as normal pointers, ... > Quote the part of the standard that says that. You mean you've been saying all this without knowing what the relevant texts say? I've been assuming all along that you were asserting that what the standard says doesn't matter - that what actual implementations do is the only thing that matters, and that you were simply unaware of the real-world implementations where such code doesn't work. That you were actually ignorant of clauses 6.11p1 and 8.29p13 of the C++ standard (the relevant details are cited in a recent response of mine to David's response) hadn't occurred to me. |
Keith Thompson <kst-u@mib.org>: Aug 10 05:22PM -0700 David Brown <david.brown@hesbynett.no> writes: [...] > The standard says that you can't do unaligned accesses. No, it doesn't. It says that unaligned accesses are undefined behavior. -- Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst> Will write code for food. void Void(void) { Void(); } /* The recursive call of the void */ |
David Brown <david.brown@hesbynett.no>: Aug 11 02:24AM +0200 On 11/08/2019 00:59, Ian Collins wrote: >> inefficient. > Solaris SPARC? > https://blogs.oracle.com/d/on-misaligned-memory-accesses You are missing a critical detail. I said that no compiler would ever rely on trapping and emulation for handling unaligned accesses to /packed/ objects. We are not talking about accessing data via a pointer here - then it makes sense on a processor like the SPARC to assume accesses are aligned, and handle anything else by crashing or slow emulation. We are talking about structs with some sort of "packed" feature. The compiler knows these are unaligned, and would use smaller accesses. It won't let the program crash - that would be pointless in the face of a packed struct. It won't rely on seriously slow trap handling when it knows without doubt that the data is misaligned - it will use appropriate smaller accesses. |
Keith Thompson <kst-u@mib.org>: Aug 10 05:32PM -0700 > That's implementation-defined (6.2.8p1). In C2011 you can determine the > alignment of a given type under a given implementation by using > _Alignof(typename). There is a possibly useful distinction that this doesn't capture. For example, on my x86_64 system, gcc has sizeof (int) == 4 and _Alignof (int) == 4. The compiler will, in the absence of implementation-specific directives, align int objects at 4-byte boundaries, and any attempt to access an int object that's not 4-byte aligned has undefined behavior. But you can successfully access int objects at odd addresses, though doing so is likely to be less efficient (but probably more efficient than accessing it a byte at a time). (Possibly compiler optimizations might result in surprising and misbehaving code in such cases.) Would it be useful to be able to query both the alignment at which objects will be allocated and the (possibly smaller) alignment at which objects can be accessed without going kaboom? [...] -- Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst> Will write code for food. void Void(void) { Void(); } /* The recursive call of the void */ |
Keith Thompson <kst-u@mib.org>: Aug 10 05:40PM -0700 > legal to take the address of an unaligned packed member - because the > standard already says that this is undefined behaviour. Thus if a > compiler wants to say it is allowed, it must document it. If you're going to talk about things that are "legal" or "allowed", please define what you mean by those words. The standard doesn't use them. Is the program ill-formed? Is its behavior undefined? Does it violate a diagnosable rule? There are very few things that are not *allowed* by the language. -- Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst> Will write code for food. void Void(void) { Void(); } /* The recursive call of the void */ |
Keith Thompson <kst-u@mib.org>: Aug 10 05:53PM -0700 > On 11/08/2019 00:59, Ian Collins wrote: >> On 11/08/2019 09:32, David Brown wrote: [...] > the face of a packed struct. It won't rely on seriously slow trap > handling when it knows without doubt that the data is misaligned - it > will use appropriate smaller accesses. Have you examined the code generated by a SPARC compiler for an unaligned access to a member of a packed structure? (I'm assuming that the compiler supports packed structures.) I don't have access to a SPARC system. Perhaps someone who does could compile this program and compare the code to access obj.x to the code to access obj.z. The "__attribute__((packed))" syntax works for gcc; replace it as needed for whatever compiler you're using. #include <iostream> #include <cstddef> int main() { struct foo { int x; char y; int z; } __attribute__((packed)); foo obj = { 10, '?', 20 }; int x_value = obj.x; int z_value = obj.z; std::cout << x_value << " at " << offsetof(struct foo, x) << "\n"; std::cout << z_value << " at " << offsetof(struct foo, z) << "\n"; } -- Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst> Will write code for food. void Void(void) { Void(); } /* The recursive call of the void */ |
Bonita Montero <Bonita.Montero@gmail.com>: Aug 11 07:23AM +0200 > access. It might well be that some OS's do, for compatibility with > binaries for related processors - but your "proof by repeated assertion" > is getting tedious. I didn't tell that every OS does this. > No compiler would /ever/ rely on trapping and emulation for handling > unaligned accesses to packed objects - that would be absurdly inefficient. The compiler doesn't care about trapping. It just compiles unaligned accesse. >> This is done only on embedded-platforms with fixed adresses of hardware >> -registers. > You have no idea what you are talking about. No, I'm knowing what I'm talking about. >> So you're in the context of a certain compiler and hardware. >> There you don't have to worry about what the standard says. > The standard says that you can't do unaligned accesses. We're talking about certain compilers and not about the standard. |
Bonita Montero <Bonita.Montero@gmail.com>: Aug 11 07:24AM +0200 > Solaris SPARC? Linux / SPARC also traps unaligned accesses. |
Bonita Montero <Bonita.Montero@gmail.com>: Aug 11 07:25AM +0200 > You are missing a critical detail. I said that no compiler would > ever rely on trapping and emulation for handling unaligned accesses > to /packed/ objects. Since you are allowed to get an address of such a packed objekt support for standalone-pointers that do the same must be guaranteed also. |
Bonita Montero <Bonita.Montero@gmail.com>: Aug 11 07:27AM +0200 > legal to take the address of an unaligned packed member - because the > standard already says that this is undefined behaviour. Thus if a > compiler wants to say it is allowed, it must document it. The standard is irrelevant here since we are talking about secific implementations with #pragma packed. |
Bonita Montero <Bonita.Montero@gmail.com>: Aug 11 07:28AM +0200 >>> to the unaligned members and use them as normal pointers, ... >> Quote the part of the standard that says that. > I already did. I corrected my posting: I said that not the standard is relevant here but the compiler-documentation since we're talking about a compiler -specific featre. |
David Brown <david.brown@hesbynett.no>: Aug 11 03:41PM +0200 On 11/08/2019 00:22, Bart wrote: > Does C not allow the address of a 32-bit int to be at anything other > than a multiple of 4, when the machine has byte-addressed memory, even > when the hardware allows it? The alignment for any given type is determined by the implementation, which will base it on the target platform's common ABI. Typically, alignment is based on the size of the type (4-byte types have 4-byte alignment, etc.) but reduced if the maximum access size for the cpu is smaller. Thus on a 16-bit target, any type 16-bit or bigger is likely to be 2 byte aligned. On a 32-bit machine, 16-bit types will be 2-byte aligned and 32-bit types will be 4-byte aligned. There is some variation - on a 32-bit machine, you might find that 8-byte doubles are 8-byte aligned, but they might be 4-byte aligned. With that alignment decision made, the C standard explicitly says that conversions to pointers that result in them being unaligned, are undefined behaviour - as is dereferencing unaligned pointers. A C implementation can, of course, give a definition for how it treats unaligned pointers - but if it does not, then you have to assume that they are simply not allowed. |
David Brown <david.brown@hesbynett.no>: Aug 11 03:52PM +0200 On 11/08/2019 01:31, James Kuyper wrote: > other method of performing such a conversion has undefined behavior > because the "Standard omits any explicit definition of the behavior..." > (3.27). Thank you for being more accurate here. I am not as familiar with the C++ standards as with the C standards - there are new C++ versions published faster than I get up to speed with them. |
Bonita Montero <Bonita.Montero@gmail.com>: Aug 11 03:55PM +0200 > With that alignment decision made, the C standard explicitly says > that conversions to pointers that result in them being unaligned, > are undefined behaviour - ... Hey, are you still that stupid? We were talking about implementations with specific support for #pragma pack! On these implementations it is perfectly legal to take an adress of an unaligned member and such pointers are indistinguishable from any other unaligned pointer. So an implemtation that has support for #pragma pack must generally support unaligned accesses. |
David Brown <david.brown@hesbynett.no>: Aug 11 05:26PM +0200 On 11/08/2019 02:53, Keith Thompson wrote: > std::cout << x_value << " at " << offsetof(struct foo, x) << "\n"; > std::cout << z_value << " at " << offsetof(struct foo, z) << "\n"; > } I don't have a SPARC compiler either - and my favourite resource <https://godbolt.org> doesn't have it. If someone could compile this code, and also show the instructions used by the compiler for accessing obj.x and obj.z, that would be nice. |
David Brown <david.brown@hesbynett.no>: Aug 11 06:06PM +0200 On 11/08/2019 15:55, Bonita Montero wrote: > Hey, are you still that stupid? We were talking about implementations > with specific support for #pragma pack! On these implementations it > is perfectly legal to take an adress of an unaligned member Reference? > and such > pointers are indistinguishable from any other unaligned pointer. Reference? > So > an implemtation that has support for #pragma pack must generally > support unaligned accesses. Reference? |
Bonita Montero <Bonita.Montero@gmail.com>: Aug 11 06:15PM +0200 >> with specific support for #pragma pack! On these implementations it >> is perfectly legal to take an adress of an unaligned member > Reference? If the compilers wouldn't allow this, they wouldn't allow taking the adddress of an unaligned member, but just accessig it with obj.member. And there must be an information that this isn't allowed in the language -reference. So you must give the reference that this isn't allowed. So show me this. >> ... and such >> pointers are indistinguishable from any other unaligned pointer. > Reference? You can assign to a pointer an aligned and unaligned element on these compilers. So the compiler can't distinguish this. |
Bonita Montero <Bonita.Montero@gmail.com>: Aug 11 06:40PM +0200 I don't even get a warning compiling that code with MSVC and gcc. #pragma pack(1) struct S { char c; int i; }; void fInc( int *p ) { ++(*p); } void f() { S s; int i; int *p; p = &s.i; fInc( p ); p = &i; fInc( p ); } |
David Brown <david.brown@hesbynett.no>: Aug 11 06:59PM +0200 On 11/08/2019 18:15, Bonita Montero wrote: >> Reference? > If the compilers wouldn't allow this, they wouldn't allow taking the > adddress of an unaligned member, but just accessig it with obj.member. Ah, the old "it compiles so it must work" argument? > And there must be an information that this isn't allowed in the language > -reference. So you must give the reference that this isn't allowed. > So show me this. I've given references to say it is undefined at the language level. If a compiler wants to override that and define its behaviour, fine - it should document it. >> Reference? > You can assign to a pointer an aligned and unaligned element on these > compilers. So the compiler can't distinguish this. Again, it is all just "it worked when I tried it". |
Bonita Montero <Bonita.Montero@gmail.com>: Aug 11 07:03PM +0200 >> If the compilers wouldn't allow this, they wouldn't allow taking the >> adddress of an unaligned member, but just accessig it with obj.member. > Ah, the old "it compiles so it must work" argument? The compiler can't warn you about everything you're doing wrong. But this would be clearly recognizable by the compiler and if this would be an issue you would at least get a warning. |
Bonita Montero <Bonita.Montero@gmail.com>: Aug 11 07:18PM +0200 > <https://godbolt.org> doesn't have it. > If someone could compile this code, and also show the instructions used > by the compiler for accessing obj.x and obj.z, that would be nice. Read this, honk: http://cmynhier.blogspot.com/2008/10/memory-alignment-on-sparc-or-300x.html But in your head, such compilers might not exist. |
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Aug 11 11:23AM +0100 Hi, "NoFussJSON" my fast C++ JSON/RJSON parser/generator now supports comments! https://github.com/i42output/neolib/blob/master/include/neolib/json.hpp That is all. /Flibble -- "Snakes didn't evolve, instead talking snakes with legs changed into snakes." - Rick C. Hodgin "You won't burn in hell. But be nice anyway." – Ricky Gervais "I see Atheists are fighting and killing each other again, over who doesn't believe in any God the most. Oh, no..wait.. that never happens." – Ricky Gervais "Suppose it's all true, and you walk up to the pearly gates, and are confronted by God," Bryne asked on his show The Meaning of Life. "What will Stephen Fry say to him, her, or it?" "I'd say, bone cancer in children? What's that about?" Fry replied. "How dare you? How dare you create a world to which there is such misery that is not our fault. It's not right, it's utterly, utterly evil." "Why should I respect a capricious, mean-minded, stupid God who creates a world that is so full of injustice and pain. That's what I would say." |
Bonita Montero <Bonita.Montero@gmail.com>: Aug 11 09:06AM +0200 > But you may be after something else. Yes. |
"Öö Tiib" <ootiib@hot.ee>: Aug 11 03:23AM -0700 On Sunday, 11 August 2019 00:45:13 UTC+3, Tim Rentsch wrote: > I asked because I was curious to know if your confusion about not > understanding the question had progressed beyond merely being > uncertain. To where uncertainty about understanding of a problem can progress? Ignorance about any and all things is default and dominant state of all minds. So the only progress from there possible seems to be towards (often vague, often incorrect,) understandings of some aspects of few things. Did you mean some other "progress"? My current understanding is that states are some kind of "modes of being" between what can be "transitions". My reading of OP request was that the "states-and-transitions" have to be implemented as "state-functions". I expressed that it feels uncommon. Alf wrote that the goal of it is in textual simplicity. Plausible. The code (even if terse) would not still look neither like a state diagram nor like any form of transition table. So I lost interest in the thread. > > Your habit to answer in useless manner starts to feel > > strange. > I'm sure other people feel the same way about your answers. My ideas may feel to be useless to many but at least I try to provide some. I meant that your lack of attempt to express any thoughts started to feel strange. Have I offended you somehow? |
You received this digest because you're subscribed to updates for this group. You can change your settings on the group membership page. To unsubscribe from this group and stop receiving emails from it send an email to comp.lang.c+++unsubscribe@googlegroups.com. |
No comments:
Post a Comment