Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

alignment and padding wrt cache lines...

46 views
Skip to first unread message

Chris M. Thomasson

unread,
Sep 10, 2017, 4:51:21 PM9/10/17
to
Here is a crude little try of mine: have not programmed this type of
base logic for efficient multi-threading in a while. So, try to not to
flame me too hard wrt the following code:
____________________________
#include <cstdio>
#include <cstdint>
#include <cstdlib>

#if ! defined (CT_CLSIZE_DEFAULT)
# define CT_CLSIZE_DEFAULT 64
#endif

#if ! defined (CT_CLSIZE)
# define CT_CLSIZE CT_CLSIZE_DEFAULT
#endif


// Change this to:
template<typename T, std::size_t T_clsize = CT_CLSIZE>
struct ct_cache_line_pad
{
alignas(T_clsize) T data;

// alignas can pad at will!
// Uncomment the following line for a forced padding error...
// unsigned char pad[T_clsize];

static_assert(sizeof(T) <= T_clsize, "T greater than cache line!");
};


// a random user defined foo...
struct foo
{
unsigned char id;
unsigned int seq;
};


int main()
{
typedef ct_cache_line_pad<foo> foo_clpad;

foo_clpad f = { { 42, 103 } };

// uncomment the (// + 1;) for forced alignment error
uintptr_t p = ((uintptr_t)&f.data); // + 1;

if (sizeof(f) > CT_CLSIZE)
{
std::printf("f over padded! %lu\n", (unsigned long)sizeof(f));
std::printf("hit <ENTER> to continue...\n");
std::fflush(stdout);
std::getchar();
}

if ((p) % (CT_CLSIZE)) // hack assertion!
{
std::printf("&f not aligned! %llu\n", p);
std::printf("hit <ENTER> to continue...\n");
std::fflush(stdout);
std::getchar();
}

std::printf("sizeof(f) = %lu\n", (unsigned long)sizeof(f));
std::printf("&f = %p\n", (void*)&f);
std::printf("&f.data = %p\n", (void*)&f.data);

std::printf("\n\n");
std::printf("f.data.id:%u\n", f.data.id);
std::printf("f.data.seq:%u\n", f.data.seq);

return 0;
}
____________________________


f needs to be padded up to a cache line size and aligned on its
boundary. Afaict, my code should check for that. Please point out any
problems you see. For instance GCC alignas pads and aligns, no need for
extra padding in the struct?

Chris M. Thomasson

unread,
Sep 10, 2017, 5:36:46 PM9/10/17
to
On 9/10/2017 1:50 PM, Chris M. Thomasson wrote:
> Here is a crude little try of mine: have not programmed this type of
> base logic for efficient multi-threading in a while. So, try to not to
> flame me too hard wrt the following code:
> ____________________________
[...]
>     if ((p) % (CT_CLSIZE)) // hack assertion!
>     {
>         std::printf("&f not aligned! %llu\n", p);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

That should at least cast to the specified type:

std::printf("&f not aligned! %llu\n", (unsigned long long)p);

;^o

[...]

Ian Collins

unread,
Sep 10, 2017, 5:43:01 PM9/10/17
to
On 09/11/17 08:50 AM, Chris M. Thomasson wrote:
> Here is a crude little try of mine: have not programmed this type of
> base logic for efficient multi-threading in a while. So, try to not to
> flame me too hard wrt the following code:
> ____________________________
> #include <cstdio>
> #include <cstdint>
> #include <cstdlib>
>
> #if ! defined (CT_CLSIZE_DEFAULT)
> # define CT_CLSIZE_DEFAULT 64
> #endif
>
> #if ! defined (CT_CLSIZE)
> # define CT_CLSIZE CT_CLSIZE_DEFAULT
> #endif


One general comment: if you are witting C++, use C++!

Don't use preprocessor "constants".

If you are going to use C standard library functions, just use the C
headers.

--
Ian

Chris M. Thomasson

unread,
Sep 11, 2017, 1:17:59 AM9/11/17
to
What about:
______________________________
#include <cstdint>
#include <cstdlib>
#include <iostream>

#if ! defined (CT_CLSIZE_DEFAULT)
# define CT_CLSIZE_DEFAULT 128
#endif

#if ! defined (CT_CLSIZE)
# define CT_CLSIZE CT_CLSIZE_DEFAULT
#endif


// Change this to:
template<typename T, std::size_t T_clsize = CT_CLSIZE>
struct ct_cache_line_pad
{
alignas(T_clsize) T data;

// alignas can pad at will!
// Uncomment the following line for a forced padding error...
// unsigned char pad[T_clsize];

static_assert(sizeof(T) <= T_clsize, "T greater than cache line!");
};


// a random user defined foo...
struct foo
{
unsigned char id;
unsigned int seq;
};


int main()
{
typedef ct_cache_line_pad<foo> foo_clpad;

foo_clpad f = { { 42, 103 } };

// uncomment the (// + 1;) for forced alignment error
std::uintptr_t p = ((std::uintptr_t)&f.data);// + 1;

if (sizeof(f) > CT_CLSIZE)
{
std::cout << "f over padded! " << sizeof(f) << "\n";
std::cout << ("hit <ENTER> to continue...\n");
std::cout.flush();
std::cin.get();
}

if ((p) % (CT_CLSIZE)) // hack assertion!
{
std::cout << "&f not aligned! " << p << "\n";
std::cout << ("hit <ENTER> to continue...\n");
std::cout.flush();
std::cin.get();
}

std::cout << "sizeof(f) = " << sizeof(f) << "\n";
std::cout << "&f = " << &f << "\n";
std::cout << "&f.data = " << &f.data;

std::cout << "\n\n";
std::cout << "f.data.id:" << (int)f.data.id << "\n";
std::cout << "f.data.seq:" << f.data.seq << "\n";

return 0;
}
______________________________

Humm... Noticed that alignas does not like 4096 as a boundary.

Chris M. Thomasson

unread,
Sep 13, 2017, 10:38:50 PM9/13/17
to
On 9/10/2017 2:42 PM, Ian Collins wrote:
> On 09/11/17 08:50 AM, Chris M. Thomasson wrote:
>> Here is a crude little try of mine: have not programmed this type of
>> base logic for efficient multi-threading in a while. So, try to not to
>> flame me too hard wrt the following code:
>> ____________________________
>> #include <cstdio>
>> #include <cstdint>
>> #include <cstdlib>
>>
>> #if ! defined (CT_CLSIZE_DEFAULT)
>> #   define CT_CLSIZE_DEFAULT 64
>> #endif
>>
>> #if ! defined (CT_CLSIZE)
>> #   define CT_CLSIZE CT_CLSIZE_DEFAULT
>> #endif
>
>
> One general comment: if you are witting C++, use C++!
>
> Don't use preprocessor "constants".

Wrt to preprocessor "constants", iirc basically all of my prior
experience involved the cache line size being represented as a
preprocessor macro.

I remember having to redefine the cache line macro from 64 to 128 on
older hyper-threaded Intel's. Iirc, they split 128 for each
hyper-thread. This was more than a decade ago. Something with 64K aliasing.
0 new messages