LINUX.ORG.RU

История изменений

Исправление firkax, (текущая версия) :

Я понятия не имею, о чем ты. Я говорил ровно про одну вещь — оптимизацию доступа по указателю в доступ по ссылке.

А, это я в одном месте невнимательно прочёл. Сейчас прочёл ещё раз и всё понятно стало.

int func(int *a)
{
    return *a * *a;
}

А тебе обязательно нужно чтобы компилятор race condition аккуратно сделал? Не вижу проблемы, тем более с умножением у которого даже порядок чтения операндов не специфицирован. Если б там было не умножение а && то порядок уже задан, но всё равно это чтение одного и того же адреса два раза подряд в соседних инструкциях, без побочных эффектов (если они есть надо указать volatile - и будут два чтения) - вполне норм читать только один раз.

Сделай вот так: *a && read(0,0,0) && *a и он будет читать два раза т.к. между чтениями стоит read() который мог что-то изменить в памяти. А вот если int * __restrict a то даже read() в середине не помешает ему выкинуть второе чтение.

Ознакамливайся: https://gist.github.com/Earnestly/7c903f481ff9d29a3dd1

Очень длинная простыня, и сложно найти в ней что-то релевантное среди мусора либо про синтаксис, либо про подсовывание битых данных стандартной библиотеке, либо ещё чего-то подобного.

----------------

Кстати, вспомнил у себя обратный случай

assert(!obj->status2 || obj->status2==4 && obj->data);
(ассерт был под локом) компилятор коварно не стал кешировать status2 (по крайней мере в -O0) и из-за этого падал на этом ассерте. Пришлось вручную ему подсказывать
assert(!(tmp=obj->status2) || tmp==4 && obj->data);
Там суть была в том, что переход откуда-то в status2==4 делался только вместе с заполнением data под локом, а вот переход status2==4 -> status2==0 делался без лока т.к. 0 менее ограничивающий чем 4 и пофиг если его кто-то не сразу заметит.

Исходная версия firkax, :

Я понятия не имею, о чем ты. Я говорил ровно про одну вещь — оптимизацию доступа по указателю в доступ по ссылке.

А, это я в одном месте невнимательно прочёл. Сейчас прочёл ещё раз и всё понятно стало.

int func(int *a)
{
    return *a * *a;
}

А тебе обязательно нужно чтобы компилятор race condition аккуратно сделал? Не вижу проблемы, тем более с умножением у которого даже порядок чтения операндов не специфицирован. Если б там было не умножение а && то порядок уже задан, но всё равно это чтение одного и того же адреса два раза подряд в соседних инструкциях, без побочных эффектов (если они есть надо указать volatile - и будут два чтения) - вполне норм читать только один раз.

Сделай вот так: *a && read(0,0,0) && *a и он будет читать два раза т.к. между чтениями стоит read() который мог что-то изменить в памяти. А вот если int * __restrict a то даже read() в середине не помешает ему выкинуть второе чтение.

Ознакамливайся: https://gist.github.com/Earnestly/7c903f481ff9d29a3dd1

Очень длинная простыня, и сложно найти в ней что-то релевантное среди мусора либо про синтаксис, либо про подсовывание битых данных стандартной библиотеке, либо ещё чего-то подобного.