Compiler constant indicating memory alignment requirement

Some processor architectures (other than x86) do not like to read and write multibyte numbers on unmanaged addresses so much that they cause a SIGBUS exception when this is detected and force the programmer to do everything manually in byte order. Although nothing can probably be done with the platforms for which it is required, it would be foolish to check alignment and perform byte operations on platforms that allow for uneven access (e.g. x86). The question is: do C / C ++ compilers define a constant indicating alignment requirement ?

I am currently using this:

#if defined(_M_IX86) | defined(__i386) | defined(__i386__) | defined(i386) | defined(_X86_) // Unaligned access is allowed. #elif defined(_M_X64) | defined(__x86_64__) | defined(__x86_64) | defined(__amd64) | defined(__amd64__) | defined(_M_AMD64) // Unaligned access is allowed. #else #define ALIGNED_ACCESS_ONLY #endif 

But it looks too "home-brew": instead of specifying the actual properties of the current hardware platform, it displays only my own considerations about x86-32 and x86-64 and the most popular constant names for these platforms.

+5
source share
3 answers

I do not technically answer your question, but I offer a workaround if there is no answer to your question.

If your code is compiled using a configure script, you can check if consistent access is required. GNU autoconf has a function for this:

http://www.gnu.org/software/autoconf-archive/ax_check_aligned_access_required.html

Basically, he compiles the following small program, launches it, and looks at the result:

 #include <stdio.h> #include <stdlib.h> int main() { char* string = malloc(40); int i; for (i=0; i < 40; i++) { string[[i]] = i; } { void* s = string; int* p = s+1; int* q = s+2; if (*p == *q) { return 1; } } return 0; } 
+1
source

A solution that does not require any validation is what I saw in the memcpy implementation. Basically, you start copying a byte of data for each byte until you get an address that is a multiple of the desired alignment.
After that, you can start copying data fragments in Word format with all the advantages that you have with a aligned address (cyclic sweep, vectorization, etc.).

You will get the best of it with large data blocks.

Apparently, neither clang nor gcc define any macro to report unattached access. ( gcc/clang -E -dM - < /dev/null -march=native ).
Some ideas you might consider:

  • Reduce need first: problems arise when using pointers. Try to avoid this by refactoring how you process your data.
  • asm : write platform- asm to load / save to / from uneven access, although it is highly dependent on the platforms you work with.
  • SSE allows for uneven access.
0
source

OP: C / C ++ compilers define a constant indicating alignment requirement?
Yes. max_align_t - the type will be the maximum alignment requirement.

If sizeof(max_align_t) > 1 , then some alignment is required.

For up to C11, see Compiler Constant Specifying Memory Alignment Requirements

-2
source

Source: https://habr.com/ru/post/1213154/


All Articles