Почему запись в 24-битную структуру не является атомарной (в то время как запись в 32-битную структуру кажется атомарной)?

Я лудильщик - в этом нет сомнений. По этой причине (и мало по какой другой) я недавно провел небольшой эксперимент, чтобы подтвердить свои подозрения, что запись в struct не является атомарной операцией, что означает, что так называемый "неизменяемый" тип значения, который пытается обеспечить соблюдение определенных ограничений, гипотетически может не достичь своей цели.

Я написал статью в блоге об этом, используя следующий тип в качестве иллюстрации:

struct SolidStruct
{
    public SolidStruct(int value)
    {
        X = Y = Z = value;
    }

    public readonly int X;
    public readonly int Y;
    public readonly int Z;
}

Хотя приведенный выше выглядит как тип, для которого никогда не может быть истинным, что X ! = Y или Y != Z, на самом деле это может произойти, если значение находится "в середине присваивания" в то же время, когда оно копируется в другое место отдельным потоком.

Ладно, большое дело. Любопытство и не более того. Но потом у меня возникла догадка: мой 64-битный процессор должен на самом деле уметь копировать 64 бита атомарно, верно? Так что если я избавлюсь от Z и ограничусь X и Y? Это всего 64 бита; должно быть возможно перезаписать их за один шаг.

Конечно, это сработало. (Я понимаю, что некоторые из вас сейчас, вероятно, нахмурили брови, думая: Да, да. Как это вообще интересно? Пошутите). Конечно, я понятия не имею, гарантировано это или нет, учитывая мою систему. Я почти ничего не знаю о регистрах, промахах кэша и т.д. (я буквально просто пересказываю услышанные термины, не понимая их значения); так что на данный момент все это для меня "черный ящик".

Следующее, что я попробовал - опять же, просто по наитию - это структура, состоящая из 32 бит, использующая 2 коротких поля. Это, казалось, также демонстрировало "атомарную присваиваемость". Но затем я попробовал 24-битную структуру, используя 3 байтовых поля: не получилось.

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

Уменьшение до 16 бит с 2 байтовыми полями: снова атомарно!

Может ли кто-нибудь объяснить мне, почему это так? Я слышал об "упаковке битов", "расположении кэш-линий", "выравнивании" и т.д., но опять же, я не знаю, что все это значит, и имеет ли это значение в данном случае. Но я чувствую, что вижу закономерность, не имея возможности точно сказать, в чем она заключается; ясность была бы очень признательна.

12
задан Dan Tao 9 February 2011 в 00:31
поделиться