Ada-Rapporteur-Group / User-Community-Input

Ada User Community Input Working Group - Github Mirror Prototype
26 stars 1 forks source link

Extended support for the non-native bit-order #86

Open ARG-Editor opened 5 months ago

ARG-Editor commented 5 months ago

This issue continues an unfinished topic from Ada 2022. This issue was created to fulfill the ARG resolution of November 10, 2022.

Adapting code to run on targets with different endiannesses has long been a problematic endeavor for Ada users. Even though Ada 2005 improved the situation compared to Ada 95 with the AI95-0133-1 binding interpretation, there was in general no way to specify a record representation clause in a way that would produce identical sequences of bytes in memories for little-endian and big-endian targets. In some cases, this could be achieved using customized representation clauses depending on the target, but in cases where some record components cross byte boundaries, there was no other working option but to introduce explicit byte swapping operations.

A new attribute Scalar_Storage_Order was proposed to improve this situation. See AI12-0218-1 for details of the proposal. (http://www.ada-auth.org/cgi-bin/cvsweb.cgi/ai12s/ai12-0218-1.txt)

ARG-Editor commented 5 months ago

Here are my personal comments on this topic.

First, it's not clear to me why one would even want a non-native bit order in memory. In general, management of memory is best left to the compiler, in order to get the best possible performance (both in time and space) for the given target.

So the use of non-native orders should be limited to interfacing, most of which is associated with streaming. The proposal notes that it has no effect on streaming, so it does not help there. It also cannot help with hardware interfacing, as that necessarily is part of the current machine and thus uses the native bit-order.

The current facilities that Ada supports were defined in order to avoid requiring support for components that would be non-contiguous in the native bit order. Accessing such components would require so-called byte swapping (although the actual problem is more complex than just that). This would be substantially larger and slower code than needed to just access bit-fields (and that is already much larger and slower than native access to components).

Making it too easy to write such code could easily result in code that runs much slower than that defined in another language. This would generally be reflected back on Ada and on the Ada implementation, rather than the suboptimal code associated. It should be hard to write code that requires byte swapping!

Adding non-contiguous component support is pervasive in an Ada compiler; almost all access code would have to be able to support it. Doing so would be a fairly large project. But such non-native code should be quite rare in practice (as noted previously); the cost is much higher than the benefit (few programmers would benefit, and only in a small section of code).

Finally, there is no formal language proposed for this idea. Someone interested would need to step up and create a complete proposal including wording. In the absence of that, this proposal is not going anywhere.

sttaft commented 5 months ago

I presume the intent was to standardize the GNAT-specific aspect Scalar_Storage_Order, which seems to be of value to many users of GNAT. The aspect is described here: https://gcc.gnu.org/onlinedocs/gcc-4.9.4/gnat_rm/Attribute-Scalar_005fStorage_005fOrder.html It is relevant for hardware interfacing and binary I/O.

jere-software commented 4 months ago

I would greatly find this useful. As an embedded programmer, in almost every project I do, I find myself having to use objects that need different endianess (usually due to interfacing with another IC to my process or a some sort of communications protocol that has a specific endianess but must interface with two separate processors of different endianess).

I basically have to write either some bytes swapping routines or shift/or logic for these things instead, so having the compiler handle it when I specify it to would be nice.

On a more fun note, I recently started writing an emulator which targets a chip with a specific endianess, but I would like my emulator to be compilable on any platform that has a valid compiler, being able to set the endianess of some of the emulated components simplifies the code and makes it more readable than having to intersperse shift/ors (or byte swaps).

I don't find the slower speed argument that compelling to be honest. The default byte order would be native, so the average programmer would not find it slower, and the folks that use this type of feature will most likely already be aware of the speed implications of mixing endianess, even via aspect