2

I defined aligned floats like this

typedef __attribute((aligned(64))) float aligned_float;

And then I define aligned floats with the restrict keyword like this

typedef aligned_float * restrict aligned_floatptr;

This works like I expect. But since I almost always want these two together I tried typedef in one line like this

typedef __attribute((aligned(64))) float * restrict aligned_floatptr2

However, this does not work. The restrict keyword is still recognized but the alignment is not. The compiler gives me no warning however. I only realized the alignment did not work by looking at the assembly.

Why does the combined definition not work and why don't I get a warning?

You can see the assembly for Clang and GCC here.


The reason I want to do this is that I have code like this

static void kernel(float * restrict a, float * restrict b, float * restrict c, int n) {
  a = __builtin_assume_aligned(a, 64);
  b = __builtin_assume_aligned(b, 64);
  c = __builtin_assume_aligned(c, 64);
  //rest of code

}

and I have MANY variations of this. I find it more convenient to use

static void kernel(aligned_flotptr a, aligned_floatptr b, aligned_floatptr c, int n) {
    //rest of code
}

I just realized that Clang does not seem to recognizing even aligned_float. It's only GCC the recognizes it. With Clang I still need to use __builtin_assume_aligned (or maybe #praga omp sind aligned). On the other hand, Clang produces good code even without alignment (unaligned instructions are as fast as the aligned versions for several generations now) so it's really really with GCC that I need alignment.

Z boson
  • 32,619
  • 11
  • 123
  • 226
  • 1
    The attribute is most likely applied on `aligned_floatptr2` and not the `float` type. – StoryTeller - Unslander Monica Apr 26 '17 at 10:08
  • @StoryTeller, I think you're right. I think it my the same as `typedef float * restrict aligned_floatptr2 __attribute((aligned(64)));` which has the same effect. I guess there is no way to do this in one typedef. That's not a big deal. It just took me a while to figure out that it was not doing what I wanted. – Z boson Apr 26 '17 at 11:17
  • 1
    1) Never typedef pointers. 2) How does it even make sense to typedef something as `restrict`? How can a type know how variables of that type will be used by the program? It is a bad idea in general to use type qualifiers inside type definitions. – Lundin Apr 26 '17 at 11:39
  • @Lundin I edited my question to explain why I want to do this. Is `intptr_t` a typedef of a int pointer? Wikiepedia give an example of typedef with pointers https://en.wikipedia.org/wiki/Typedef#Using_typedef_with_pointers . Why should I never do this? – Z boson Apr 26 '17 at 11:53
  • 1
    @Zboson - The examples in Wikipedia are not normative to say the least. This one in particular is a toy example that should be removed for the bad practice it demonstrates as a side effect. – StoryTeller - Unslander Monica Apr 26 '17 at 11:55
  • @Zboson: `intptr_t` is not a typedef of an int pointer, it's just named that way because it is the signed integer type that can temporarily hold the value of any `void` pointer. The reason you should not typedef pointers is that it makes the code much harder to understand correctly for us humans, and in a way that makes misunderstanding easier/more likely than correct understanding -- nasty gotchas with no upsides (other than maybe making writing the initial version of the code easier). – Nominal Animal Apr 26 '17 at 12:39
  • @Zboson `intptr_t` is an integer, not a pointer. As per the very definition of that type's usage: to be large enough to hold a pointer converted to an integer. I don't know which amateur hobbyist that wrote the linked Wikipedia article, but that's Wikipedia's problem... The reason why you shouldn't hide pointers behind typedefs is because it leads to confusion and makes the code unreadable. There is a broad industry consensus about this and it has been debated many times before on SO. – Lundin Apr 26 '17 at 12:55
  • 1
    @Lundin `intptr_t` was a stupid example. Wikipedia typedef a int pointer they called `intptr` and I confused it with `intptr_t`. Okay, this is the first time I typedef a pointer. I admit I did not like it at first because it's not clear it's a pointer anymore but on the other hand it removed a lot of code duplication. `floatptr a` which I have many times is a lot shorter than `float * restrict a`. I get a huge benefit with `restrict` in dense matrix multiplication. – Z boson Apr 26 '17 at 13:21
  • 2
    @Zboson "Saving key presses" is a terrible rationale for changing the program design. If you feel that the original declaration line turned to long, you can format the code so that each function parameter ends up on a line of its own. – Lundin Apr 26 '17 at 13:27
  • BTW: C11 (maybe C99) offers `alignas`, so maybe use `typedef alignas(64) float aligned_float;` for portability. Also: why 64? – chux - Reinstate Monica Apr 26 '17 at 13:43
  • @chux as far as I can tell you cannot typedef `alignas` – Z boson Apr 27 '17 at 06:57
  • @Lundin, I got the idea for typedef for a pointer with restrict from [herer](http://stackoverflow.com/a/4175350/2542702) and [here](https://stackoverflow.com/questions/2748818/c-c-restrict-type). – Z boson Apr 27 '17 at 07:03
  • @chux, the most portable way I know for alignment is to use `#pragma omp simd aligned(a,b,c:64)`. That works for GCC, Clang, and ICC but not MSVC. The alignment probably only needs to be 32 (AVX). I don't have a good reason to use 64. The alignment only matters because GCC produces much better code when it's aligned (Clang produces good code either way). – Z boson Apr 27 '17 at 09:43

0 Answers0