I am not sure how it is in c, but alignment seem
to be mess in the world of c and c++
Is it standarized as to today state of these
languages?
(to include such solution to language seem to be
easy for me, just some thing like
align(4096) int table[4096];
or some better looking modifier that could be
used for any thing needed to be define aligned)
You can create a macro that leverages either C11 alignas or a compiler
extension to align an array. This is an excerpt from the library I'm
working on.
\code
/* The symbol 'stdalign_alignof_defined' is temporarily used to
record whether or not the 'alignof' macro is available. */
#undef stdalign_alignof_defined
/* The symbol 'stdalign_alignas_defined' is temporarily used to
record whether or not the 'alignas' macro is available. */
#undef stdalign_alignas_defined
/*
* If C11 standard support is available, then 'alignof' is directly
* available, and the declaration syntax for a typed variable with
* aligned storage can be defined directly in terms of 'alignas'.
*/
#if defined(__STDC__) && defined(__STDC_VERSION__)
# if (__STDC__ && __STDC_VERSION__ >= 201112L)
# include <stdalign.h>
# if defined(__alignof_is_defined)
# define stdalign_alignof_defined
# endif
# if defined(__alignas_is_defined)
# define stdalign_alignas_defined
# endif
# endif
#endif
/*!
* \brief Determine the alignment of the type in bytes.
* \param type A type.
*
* The number of bytes returned is not guaranteed to be the smallest
* alignment allowed by the platform if \c alignof is not natively
* available from the compiler. Without \c alignof, the \c offsetof
* operator can determine a compatible alignment for the given type.
*
* \usage
* \include align/alignof_example.c
*
* The example above should display something similar to the
* following.
*
* \code
* alignof example
* -------------------------------------
* | type | sizeof | alignof |
* -------------------------------------
* char 1 1
* short int 2 2
* int 4 4
* long int 4 4
* long long int 8 8
* float 4 4
* double 8 8
* long double 12 4
* size_t 4 4
* ptrdiff_t 4 4
* void* 4 4
* enum align_e 4 4
* struct align_s 16 8
* align_func 4 4
*
* ALIGN_MAX = 8
* \endcode
*/
#if !defined(stdalign_alignof_defined)
# define alignof(type) (offsetof (struct { char c; type t; }, t))
#endif
#undef stdalign_alignof_defined
/*!
* \brief Declare a variable with aligned storage.
* \param type The type.
* \param alignment The alignment constraint.
*
* This macro depends on the availability of \c alignas in C11 or
* compiler extensions such as \c __attribute__ or \c __declspec to
* specify an alignment constraint. An alignment constraint can be
* specified when declaring variables with static or automatic
* storage or for variables declared in \c struct definitions.
*
* \usage
* \include align/c_aligned_storage_example.c
*
* The example above should display something similar to the
* following.
*
* \code
* fv1 0022ff60 = [1,2,3,4]
* fv2 0022ff50 = [5,6,7,8]
*
* dot product = 70
* \endcode
*
* The key to using the aligned intrinsic \c _mm_load_ps in the
* dot product function is to ensure that the vectors \c fv1 and
* \c fv2 are aligned to an address on a 16-byte boundary.
*
* The alignment of variables with static storage is dependent on
* the capabilities of the linker. If the linker is only able to
* align variables up to a maximum of 16 bytes, then requesting a
* buffer with a stricter alignment is not possible. Often the
* compiler will generate a warning if an alignment constraint
* cannot be met.
*/
#if defined(stdalign_alignas_defined)
# define c_aligned_storage(type, alignment) alignas(alignment) type
#else
# if defined(__GNUC__)
# define c_aligned_storage(type, alignment) type
__attribute__((aligned (alignment)))
# elif defined(_MSC_VER) && (_MSC_VER >= 1310)
# define c_aligned_storage(type, alignment) __declspec(align
(alignment)) type
# else
# define c_aligned_storage(type, alignment) type
# endif
#endif
#undef stdalign_alignas_defined
\endcode
Then you can use it like the following
\code
#include <stdio.h>
#include <xmmintrin.h>
#include <clover/constraint.h>
#include <clover/align.h>
/* SSE Intrinsics support must be enabled by adding '-msse' to
gcc or '/arch:SSE' to cl. */
static inline void sse_v4sf_dot( float* dot,
const float* v1,
const float* v2 )
{
__m128 mv1, mv2, mbuf1, mbuf2;
mv1 = _mm_load_ps( v1 );
mv2 = _mm_load_ps( v2 );
mbuf1 = _mm_mul_ps( mv1, mv2 );
mbuf2 = _mm_shuffle_ps( mbuf1, mbuf1, _MM_SHUFFLE( 3, 2, 3, 2 ) );
mbuf1 = _mm_add_ps( mbuf1, mbuf2 );
mbuf2 = _mm_shuffle_ps( mbuf1, mbuf1, _MM_SHUFFLE( 0, 1, 0, 1 ) );
mbuf1 = _mm_add_ss( mbuf1, mbuf2 );
_mm_store_ss( dot, mbuf1 );
}
int main( void )
{
float dot_product;
c_aligned_storage(float, 16) fv1[4] = { 1, 2, 3, 4 };
c_aligned_storage(float, 16) fv2[4] = { 5, 6, 7, 8 };
printf( "fv1 %p = [%.0f,%.0f,%.0f,%.0f]\n",
fv1, fv1[0], fv1[1], fv1[2], fv1[3] );
printf( "fv2 %p = [%.0f,%.0f,%.0f,%.0f]\n",
fv2, fv2[0], fv2[1], fv2[2], fv2[3] );
printf( "\n" );
c_exit_if_fail( c_is_aligned_ptr( fv1, 16 ),
"Vector not properly aligned for SSE" );
c_exit_if_fail( c_is_aligned_ptr( fv2, 16 ),
"Vector not properly aligned for SSE" );
sse_v4sf_dot( &dot_product, fv1, fv2 );
printf( "dot product = %.0f\n", dot_product );
return 0;
}
\endcode
Best regards,
John D.
P.S. I have not actually tested it on a C11 compiler yet ... will get
there eventually