Cache line mark for variables that are a multiple of the size of the cache line

I create a very fast multi-threaded system for modeling discrete events. The core of the structure uses atomatics and contactless programming techniques to achieve very fast execution in many threads. This requires me to bind some variables to cache lines and pad the remaining cache line space so that I have no argument regarding the cache line. Here is how I do it:

// compute cache line padding size
constexpr u64 CLPAD(u64 _objSize) {
  return ((_objSize / CACHELINE_SIZE) * CACHELINE_SIZE) +
      (((_objSize % CACHELINE_SIZE) > 0) * CACHELINE_SIZE) -
      _objSize;
}

alignas(CACHELINE_SIZE) MyObject myObj;
char padding[CLPAD(sizeof(myObj))];

This works fine for me, but today I came across a problem when I used this methodology for a new type of object. The CLPAD () function returns the number of characters required to enter an input type to the next cache line. However, if I insert a type whose size is exactly equal to the number of cache lines, CLPAD returns 0. If you try to create an array of zero size, you will get this warning / error:

ISO C++ forbids zero-size array 'padding'

I know that I can modify CLPAD () to return CACHELINE_SIZE in this case, but then I burn the line in the cache without spaces.

How can I make a fill-in declaration disappear if CLPAD returns 0?

+4
source share
1 answer

std::aligned_storage<>, :

template<class T, bool = false>
struct padded
{
    using type = struct
    {
        alignas(CACHELINE_SIZE)T myObj;
        char padding[CLPAD(sizeof(T))];
    };
};

template<class T>
struct padded<T, true>
{
    using type = struct
    {
        alignas(CACHELINE_SIZE)T myObj;
    };
};

template<class T>
using padded_t = typename padded<T, (sizeof(T) % CACHELINE_SIZE == 0)>::type;

:

struct alignas(32) my_type_1 { char c[32]; }; // char c[32] to silence MSVC warning
struct my_type_2 { char c[CACHELINE_SIZE * 2]; }; // ditto

int main()
{
    padded_t<my_type_1> pt0;
    padded_t<my_type_2> pt1;

    sizeof(pt0);    // 128
    alignof(pt0);   // 128

    sizeof(pt1);    // 256
    alignof(pt1);   // 128
}

myObj, .

+3

Source: https://habr.com/ru/post/1677512/


All Articles