When writing subroutines which are amenable to vectorization it can be helpful to provide alignment hints. This requires that the memory be aligned at boundaries of size of the vector register length.
There are several ways to obtain aligned memory:
- compiler directives
- Intel Fortran:
!DIR$ ATTRIBUTES ALIGN: n :: object
- IBM XL Fortran:
!IBM* ALIGN(n, object)
- Intel Fortran:
- compiler flags
- Intel Fortran:
-align arraynbyte
- NVIDIA nvfortran:
-Mcache_align
- Intel Fortran:
- manual memory management “F77 style” (use of a static memory pool and the non-standard
loc
extension to position arrays at aligned boundaries) - use
pointer
arrays with memory allocated via C (or C++) library routines:aligned_alloc
(C11, C++17)- operator
new[]
(aligned version since C++17) posix_memalign
(POSIX)-
_aligned_malloc
(Windows) _mm_malloc
(Intel, GCC, clang, on x86-64)mkl_malloc
(Intel oneMKL, C and Fortran versions available)fftw_malloc
(FFTW)
- the OpenMP 5.1
allocate
directive withalign
clause (!$omp allocate align(...)
)
Perhaps someone else is aware of alignment control directives from other vendors (Cray, NVIDIA, AMD)? gfortran and flang don’t appear to have them. (Alignment attributes are available for C/C++ with gcc and clang.) If you know of other options, I will add them to list.
Going forward, the OpenMP directive combined with !$omp simd
for explicit vectorization control appears to be the most portable option, assuming that vendors will come to support it.
What would be required to make alignment part of the base language allocate()
statement? Does it even make sense without a memory model or OS support for dealing with different CPU modes and protection rings?
References
- Data Alignment to Assist Vectorization | Intel
- Vectorization for Intel® C++ & Fortran Compiler (PDF, 3.6 MB)
- Bug 41209 - Add full ATTRIBUTE support to gfortran (ALIGN, (WEAK)ALIAS, …) | GCC Bugzilla
- Allocating Aligned Memory Blocks | The GNU C Library
- Common Variable Attributes | GCC Online Documentation