Почему double в C выровнен на 8 байтов?
Я читал статью о выравнивании типов данных в памяти ( здесь), и я не могу понять одну точку, т.е.
Обратите внимание, что двойная переменная будет размещена на 8-байтовой границе на 32-битной машине и требует двух циклов чтения из памяти. На 64-битной машине, основанной на количестве банков, двойная переменная будет размещена на границе 8 байт и требует только один цикл чтения из памяти.
Я сомневаюсь: почему двойные переменные нужно размещать на границе 8 байтов, а не на 4 байтах? Если он размещен на границе 4 байта, нам все равно нужно всего 2 цикла чтения из памяти (на 32-битной машине). Поправь меня, если я ошибаюсь.
Также, если у кого-то есть хорошее руководство по выравниванию элементов / памяти, пожалуйста, поделитесь.
4 ответа
Причина выравнивания значения данных размером 2^N по границе 2^N состоит в том, чтобы избежать возможности того, что значение будет разбито по границе строки кэша.
Процессор x86-32 может извлечь двойное значение из любой границы слова (выровнено по 8 байт или нет) не более чем в двух 32-разрядных чтениях памяти. Но если значение разбито по границе строки кэша, то время для извлечения 2-го слова может быть довольно длинным из-за необходимости извлечения 2-й строки кеша из памяти. Это приводит к ненужной низкой производительности процессора. (На практике современные процессоры не извлекают 32-битные данные из памяти за раз; они имеют тенденцию извлекать гораздо большие значения на гораздо более широких шинах, чтобы обеспечить действительно высокую пропускную способность данных; фактическое время для извлечения обоих слов, если они находятся в той же строке кэша, и уже кэшированы, может быть только 1 такт).
Свободным следствием этой схемы выравнивания является то, что такие значения также не пересекают границы страницы. Это исключает возможность сбоя страницы в середине выборки данных.
Таким образом, вы должны выровнять двойные по 8-байтовым границам из соображений производительности. И составители знают это и просто делают это для вас.
Выравнивание значения на более низкой границе, чем его размер, делает его склонным к разделению на две линии кеша. Разделение значения на две строки кэша означает дополнительную работу по извлечению строк кэша в резервное хранилище (будет удалено две строки кэша вместо одной), что является бесполезной загрузкой шин памяти.
8-байтовое выравнивание для двойной на 32-битной архитектуре не уменьшает чтение памяти, но все же улучшает производительность системы с точки зрения уменьшения доступа к кешу. Пожалуйста, прочитайте следующее: /questions/44861297/neobhodimo-li-8-bajtovoe-vyiravnivanie-dlya-dvojnogo-tipa/44861315#44861315
См. Эту статью в вики о формате с плавающей запятой двойной точности
Количество циклов памяти зависит от вашей аппаратной архитектуры, которая определяет, сколько у вас банков оперативной памяти. Если у вас 32-битная архитектура и 4 банка ОЗУ, вам нужно только 2 цикла чтения для чтения (каждый банк ОЗУ вносит 1 байт)