3

I have many data array defined in my code with the length only specified in the array initializer.

int a[] = {1, 2, 3, 4};
int b[] = {1, 2, 3, 4, 5};

For cache line coherence consideration, I want to padding them to cache line size (32). The following code can be used without scarifying the exact size information

struct {
   int payload[4];
} __attribute__((aligned(32))) a = {
   .payload = {1, 2, 3, 4}
};

struct {
   int payload[5];
} __attribute__((aligned(32))) b = {
   .payload = {1, 2, 3, 4, 5}
};

// sizeof(a.payload) == 4 * sizeof(int), sizeof(b.payload) == 5 * sizeof(int)

However, there are quite a bundle of such data, it is hard to manually rewrite them one by one. Is there a way to define a macro to handle this, like

#define ARRAY_INITIALIZER (array, initializer) ...
#define ARRAY_PAYLOAD(array) array.payload
ARRAY_INITIALIZER(a, {1, 2, 3, 4});
ARRAY_INITIALIZER(b, {1, 2, 3, 4, 5});

The most difficulty thing here is how to calculate the length of initializer here, don't get any direction for it, can anyone help here?

9
  • This might be useful: stackoverflow.com/questions/2124339/… Yes, it is C++, but the macro definition might work for you too. Commented Aug 6, 2024 at 8:05
  • Could __attribute__((aligned(32))) be applied to the array as a single variable, but not a structure field? Commented Aug 6, 2024 at 8:15
  • Why place the arrays in a struct? Is your real question how to get the initial arrays 32-byte aligned? Commented Aug 6, 2024 at 10:56
  • 2
    @nielsen, putting it inside a struct has 2 effect 1) end data padding, not only align on start, but also align on end 2) sizeof can still get the actual size without the end padding Commented Aug 6, 2024 at 11:01
  • 1
    @StasSimonov, aligned to variable will only make it start aligned, say a array of 5 is start align on 32, the left 27 bytes are still available for other variables to allocate, we want it occupies the full 32 byte to avoid cache coherence issue Commented Aug 6, 2024 at 11:02

2 Answers 2

5

This initialization produces the aligned addresses either in C or C++:

#include <stdalign.h>

alignas(32) int a[] = {1, 2, 3, 4} ;
alignas(32) int b[] = {1, 2, 3, 4, 5};
Sign up to request clarification or add additional context in comments.

1 Comment

sizeof(b) is 20 which is not 32 byte aligned, which leave the possibility that b and other variables are in the same cache line which may cause potential problems
3

Here's one idea using variadic macros:

#include <stdalign.h> // for "alignas" - not needed since C23

#define VA_COUNT(...) (sizeof((int[]){0, __VA_ARGS__}) / sizeof(int) - 1)

#define ARRAY_INITIALIZER(V, ...)                       \
    struct {                                            \
        alignas(32) int payload[VA_COUNT(__VA_ARGS__)]; \
    } V = {.payload = {__VA_ARGS__}}

Note that the standard _Alignas (alignas) is used to align the array. The payload size is calculated by using VA_COUNT.

Example use:

#include <stdio.h>

// the macro definitions from above goes here

#define SIZE(x) (sizeof(x) / sizeof *(x))

int main(void) {
    ARRAY_INITIALIZER(a, 1, 2, 3, 4);

    for (unsigned i = 0; i < SIZE(a.payload); ++i) {
        printf("%d\n", a.payload[i]);
    }
}

Output:

1
2
3
4

3 Comments

Hi Ted. In my environment I don't have alignas so I still use__attribute__((aligned(32))) after the struct. I am also changing the {0, __VA_ARGS__} to __VA_ARGS__ because I want the _VA_ARGS hold the full {...} initializer, and the result is OK. Any reason you add an extra 0 for it? I check sizeof((int[]){}) and it can compile OK
@EricSun Don't you have _Alignas either? It's in the language since C11, but perhaps you are using an older standard? I recommend that you do not remove the extra 0 and the -1 to compensate. Not that it matters much since you will not use it with empty parameter lists but there's no reason to make the macro fragile. Demo
Understand Ted. BTW godbolt.org is new to me and seems very useful. Thank you for the help!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.