- Performance of unaligned memory-accesses - 13 Updates
- Why can't I understand what coroutines are? - 2 Updates
Bart <bc@freeuk.com>: Aug 11 07:00PM +0100 On 11/08/2019 14:55, Bonita Montero wrote: > pointers are indistinguishable from any other unaligned pointer. So > an implemtation that has support for #pragma pack must generally > support unaligned accesses. On one simple C compiler I use (actually, my own) '#pragma pack(1)' simply disables the padding that would otherwise be inserted to ensure proper alignment. It doesn't consider the legality of such accesses, although the whole compiler does assume the target is byte-addressable (offsets of struct members are byte-offsets from the start). |
Bonita Montero <Bonita.Montero@gmail.com>: Aug 11 09:06PM +0200 > It doesn't consider the legality of such accesses, although the whole > compiler does assume the target is byte-addressable (offsets of struct > members are byte-offsets from the start). But if the compiler does support #pragma pack it does generate code that the developer intended. If the code really runs depends on the CPU and if the CPU doesn't support unaligned acesses, it depends on the OS to emulate the access through trapping. The Oracle C++ compiler has support for pragma pack and unaligned accesses. With this compiler you have three choices: 1. Unaligned accesses are emulated through emulating a load by assem- bling the bytes in memory to the larger data type. But that means every access is assembled / disassembled in that way because the compiler can't distinguish all unaligned and aligned acceses. That feature could be of course implemented on a per-translationunit basis. 2. Unaligned accesses are just compiled like other accesses and the compiler is instructed to let the OS emulate this accesses by trapping I guess that's not really a compiler-feaute, i.e. that's not per trans- lation-unit but the compiler does forward this option to the linker which sets this for the whole executable. 3. Unaligned accesses are forced to cause a SIGBUS. |
Keith Thompson <kst-u@mib.org>: Aug 11 01:07PM -0700 Bart <bc@freeuk.com> writes: [...] > It doesn't consider the legality of such accesses, although the whole > compiler does assume the target is byte-addressable (offsets of struct > members are byte-offsets from the start). And what happens if a program accesses a misaligned member? #pragma pack(1) struct foo { char c; int i; } obj = { 0 }; printf("%d\n", obj.i); If your compiler targets x86 and/or x86_64, such an access will probably just work. On other targets, it might blow up -- and if so, I would seriously question the wisdom of claiming to support #pragma pack(1). -- 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 11 01:11PM -0700 David Brown <david.brown@hesbynett.no> writes: [...] > 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. (Did you mean to say "C++ standard"?) You weaken your argument by using phrases like "not allowed". There are very few things that are not allowed by the standard. For undefined behavior, the compiler is not obligated to diagnose the problem, and the run-time behavior *can* be exactly what someone might naively expect. I suggest sticking to the terms defined by the standard itself. -- 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 11:00PM +0200 On 11/08/2019 19:18, Bonita Montero wrote: > 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. I never said anything remotely like that. First, I did not say that no OS emulates unaligned accesses - I said that you were wrong to say that /every/ OS did so, and I challenged you to find a reference to even /one/ example that does. It turns out that some OS's /do/ emulate unaligned accesses, such as Solaris - but you didn't know even one real sample when you blatantly declared that it applied to all OS's. Secondly, I said that no compiler would rely on OS emulation for unaligned /packed/ field access. This reference does not mention packed structs - ergo, it is irrelevant to the subthread. |
Bonita Montero <Bonita.Montero@gmail.com>: Aug 11 11:44PM +0200 > First, I did not say that no OS emulates unaligned accesses - > I said that you were wrong to say that /every/ OS did so, ... I didn't say that every OS does this. > ..., and I challenged you to find a reference to even /one/ > example that does. The lattter link to the example with Solaris is a reference on that. > Secondly, I said that no compiler would rely on OS emulation for > unaligned /packed/ field access. That's stupid. Some compilers might rely on the emulation, some compilers might do the disassemby and assembly of the data-word themselfes. |
Bonita Montero <Bonita.Montero@gmail.com>: Aug 11 11:46PM +0200 > That's stupid. Some compilers might rely on the emulation, some > compilers might do the disassemby and assembly of the data-word > themselfes. And as I told the Oracle C/C++ compiler on solaris can do both. |
David Brown <david.brown@hesbynett.no>: Aug 11 11:48PM +0200 On 11/08/2019 19:03, Bonita Montero wrote: >>> 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. Correct. What you are doing with unaligned pointers is likely to be wrong, but the compiler is not warning you. > But this would be clearly recognizable by the compiler and if this > would be an issue you would at least get a warning. You might think so - and I would like that to be the case. But very often, compilers do not warn about things that are clearly wrong, especially with default options. gcc can warn about various unaligned pointer cases, but only if you enable the warnings. This is not a perfect situation IMHO - I'd rather have these warnings enabled by default. Unfortunately, because some people think the rules of the language don't apply to them, there is quite a bit of code that works in practice while falling foul of this sort of thing, and that would lead to many warnings and annoyed users. After all, undefined behaviour means no guarantees of success, not a guarantee of failure. And many programmers are happy enough with "it worked when I tried it" rather than writing careful and correct code. |
David Brown <david.brown@hesbynett.no>: Aug 11 11:59PM +0200 On 11/08/2019 22:11, Keith Thompson wrote: >> unaligned pointers - but if it does not, then you have to assume that >> they are simply not allowed. > (Did you mean to say "C++ standard"?) I had been quoting from the C standards, because I am more familiar with them. James showed similar quotations from the C++ standards. > the problem, and the run-time behavior *can* be exactly what someone > might naively expect. > I suggest sticking to the terms defined by the standard itself. Fair enough. I have been a little too colloquial in my language. Yes, I did mean "undefined behaviour". And that means the standards say nothing about the results - there are no guarantees of getting the effects you want (unless the compiler documentation gives additional information), but equally nothing to say that you /won't/ get the results you want. |
Bonita Montero <Bonita.Montero@gmail.com>: Aug 12 12:15AM +0200 >> The compiler can't warn you about everything you're doing wrong. > Correct. What you are doing with unaligned pointers is likely to > be wrong, but the compiler is not warning you. It is ridiculous to expect a compiler for an CPU-architecture which supports unaligned operations not to support this. There are useful applications for this and there's nothing to do to implement this (supporting pointers to operate on unaligned data; supporting #pragma pack of course needs special implementation). So the people expect this to work. And there's no technical reason why this might not work as expected on these architectures. |
Bart <bc@freeuk.com>: Aug 11 11:58PM +0100 On 11/08/2019 21:07, Keith Thompson wrote: > probably just work. On other targets, it might blow up -- and if > so, I would seriously question the wisdom of claiming to support > #pragma pack(1). Actually, most of the time when pack(1) is used, elements will be properly aligned anyway. Because they will be sized and arranged manually to get the most efficient packing. When done properly, then I should be able to comment out the pack(1), and it ought to still work, and with the same sizes of structs, and the same member offsets. But pack(1) can also be used to define a particular layout, in instances where I don't need to access individual misaligned members, just to get the right overall size. More difficult is supporting pack(1) when a machine doesn't have byte-addressability, but I don't know if that is common these days. (My own compilers target x64. A quick test involving passes over an array of 100 million of your structs, took 1.33 seconds with normal alignment to write to and read from the .i element (all unoptimised code). Using pack(1), that increased to 1.57 seconds. But this included multiplication by 5 for each access. When I manually optimised that out, the timing went down to 1.26 seconds; faster then aligned access! I guess because 37.5% less memory was used, coupled with the x64's apparently efficient handling of misaligned reads and writes.) |
David Brown <david.brown@hesbynett.no>: Aug 12 01:02AM +0200 On 11/08/2019 23:46, Bonita Montero wrote: >> compilers might do the disassemby and assembly of the data-word >> themselfes. > And as I told the Oracle C/C++ compiler on solaris can do both. The link does not mention packed structs! How many times can I repeat this and /still/ you don't get it? |
David Brown <david.brown@hesbynett.no>: Aug 12 01:06AM +0200 On 12/08/2019 00:15, Bonita Montero wrote: >> be wrong, but the compiler is not warning you. > It is ridiculous to expect a compiler for an CPU-architecture which > supports unaligned operations not to support this. Sorry, I thought we were talking about programming in C++, not in assembly. > There are useful > applications for this There are a few occasions when it could be useful, but none where it could not be handled just as well using methods that are defined behaviour. (Either defined by the standards, or defined - documented - by the compiler.) > pack of course needs special implementation). So the people expect > this to work. And there's no technical reason why this might not > work as expected on these architectures. Certainly some people expect it to work. The question is whether compiler writers expect it to work. I can't tell what compiler writers are thinking, but I can certainly tell what they write in their documentation, and I have not seen them saying that unaligned accesses are supported except by very specific use of packed structs. |
Christian Gollwitzer <auriocus@gmx.de>: Aug 11 10:19PM +0200 Am 10.08.19 um 10:43 schrieb Alf P. Steinbach: >> this correctly means either a different stack management, or a special >> algorithm invented by geniuses which can walks along the tree leafs- > Iterative in-order isn't that hard. By the algorithm "invented by geniuses" for this particular case I was referring to Morris traversal, which walks a tree in in-order sequence with O(1) space and time. See e.g. https://www.geeksforgeeks.org/inorder-tree-traversal-without-recursion-and-without-stack/ It modifies the tree along its way, but restores it when you do the full traversal. That would be the most efficient method, at the expense of head-scratching and that you can't stop it in the middle without ruining your data structure. Christian |
Juha Nieminen <nospam@thanks.invalid>: Aug 11 09:16PM > if (root->left) bftraverse(root->left); > if (root->right) bftraverse(root->right); > } Since, as far as I understand, C++20 coroutines are stackless, I don't understand how that can work. What happens when a coroutine calls itself recursively? Does it create a new set of local variables with operator new every time it calls itself recursively? That sounds like it would be horrendously inefficient in all kinds of ways. |
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