Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
466 views
in Technique[技术] by (71.8m points)

c - How to tell GCC that a pointer argument is always double-word-aligned?

In my program I have a function that does a simple vector addition c[0:15] = a[0:15] + b[0:15]. The function prototype is:

void vecadd(float * restrict a, float * restrict b, float * restrict c);

On our 32-bit embedded architecture there is a load/store option of loading/storing double words, like:

r16 = 0x4000  ;
strd r0,[r16] ; stores r0 in [0x4000] and r1 in [0x4004]

The GCC optimizer recognizes the vector nature of the loop and generates two branches of the code - one for the case where the 3 arrays are double word aligned (so it uses the double load/store instructions) and the other for the case that the arrays are word-aligned (where it uses the single load/store option).

The problem is that the address alignment check is costly relative to the addition part and I want to eliminate it by hinting the compiler that a, b and c are always 8-aligned. Is there a modifier to add to the pointer declaration to tell this to the compiler?

The arrays that are used for calling this function have the aligned(8) attribute, but it is not reflected in the function code itself. is it possible to add this attribute to the function parameters?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

If the attributes don't work, or aren't an option ....

I'm not sure, but try this:

void vecadd (float * restrict a, float * restrict b, float * restrict c)
{
   a = __builtin_assume_aligned (a, 8);
   b = __builtin_assume_aligned (b, 8);
   c = __builtin_assume_aligned (c, 8);

   for ....

That should tell GCC that the pointers are aligned. From that whether it does what you want depends on whether the compiler can use that information effectively; it might not be smart enough: these optimizations aren't easy.

Another option might be to wrap the float inside a union that must be 8-byte aligned:

typedef union {
  float f;
  long long dummy;
} aligned_float;

void vedadd (aligned_float * a, ......

I think that should enforce 8-byte alignment, but again, I don't know if the compiler is smart enough to use it.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...