Подтвердить что ты не робот

Выравнивание строки кэша и знание размера строки кэша

Чтобы предотвратить ложное совместное использование, я хочу, чтобы каждый элемент массива был привязан к строке кэша. Поэтому сначала мне нужно знать размер строки кэша, поэтому я назначаю каждому элементу столько байтов. Во-вторых, я хочу, чтобы начало массива было выровнено с линией кэша.

Я использую Linux и 8-ядерную платформу x86. Сначала, как найти размер строки кеша. Во-вторых, как я выравниваю строку кэша в C. Я использую компилятор gcc.

Таким образом, структура будет следовать, например, при условии, что размер строки кэша равен 64.

element[0] occupies bytes 0-63
element[1] occupies bytes 64-127
element[2] occupies bytes 128-191

и т.д., предполагая, что 0-63 выровнена с линией кэша.

4b9b3361

Ответ 1

Чтобы узнать размеры, вам нужно посмотреть его, используя документацию для процессора, afaik не существует программного способа сделать это. Однако на стороне плюса большинство строк кэша имеют стандартный размер, основанный на стандартах международных стандартов. Тем не менее, в x86-кеш-кешках используется 64 байта, чтобы предотвратить ложное совместное использование, вам необходимо следовать рекомендациям процессора, на который вы нацеливаетесь (у Intel есть некоторые специальные примечания к его процессорам на основе netburst), как правило, вам нужно выровнять до 64 байтов для этого (Intel заявляет, что вам также следует избегать пересечения 16 байтовых границ).

Для этого в C или С++ требуется, чтобы вы использовали стандартную функцию aligned_alloc или один из специфичных для компилятора спецификаторов, таких как __attribute__((align(64))) или __declspec(align(64)). Чтобы проложить между членами в структуре, чтобы разделить их на разные строки кэша, вам нужно вставить элемент, достаточно большой, чтобы выровнять его до следующего 64-байтового boundery

Ответ 2

Я использую Linux и 8-ядерную платформу x86. Сначала, как найти размер строки кэша.

$ getconf LEVEL1_DCACHE_LINESIZE
64

Передайте значение в качестве определения макроса компилятору.

$ gcc -DLEVEL1_DCACHE_LINESIZE=`getconf LEVEL1_DCACHE_LINESIZE` ...

Во время выполнения sysconf(_SC_LEVEL1_DCACHE_LINESIZE) можно использовать для получения размера кеша L1.

Ответ 3

Другим простым способом является просто cat/proc/cpuinfo:

cat/proc/cpuinfo | grep cache_alignment

Ответ 4

posix_memalign или valloc можно использовать для выравнивания выделенной памяти в строке кэша.

Ответ 5

Нет абсолютно переносного способа получить размер кешлайн. Но если вы находитесь на x86/64, вы можете вызвать команду cpuid, чтобы получить все, что вам нужно знать о кеше, включая размер, размер келины, количество уровней и т.д.

http://softpixel.com/~cwright/programming/simd/cpuid.php

(немного прокрутите страницу, страница о SIMD, но в ней есть раздел, получающий кеглину.)

Что касается выравнивания ваших структур данных, также нет полностью переносного способа сделать это. GCC и VS10 имеют разные способы указать выравнивание структуры. Один из способов "взломать" его - наклеить вашу структуру неиспользуемыми переменными до тех пор, пока она не сравняется с желаемым выравниванием.

Чтобы выровнять ваш mallocs(), все компиляторы основного потока также выровняли функции malloc для этой цели.

Ответ 6

Если кому-то интересно узнать, как сделать это легко в С++, я создал библиотеку с классом CacheAligned<T>, которая обрабатывает определение размера строки кэша, а также выравнивание для вашего объекта T, на который ссылается вызов .Ref() объекта CacheAligned<T>. Вы также можете использовать Aligned<typename T, size_t Alignment>, если заранее знаете размер строки кэша, или просто хотите придерживаться очень общего значения 64 (байтов).

https://github.com/NickStrupat/Aligned