Re[6]: Как вышло, что наложение предполагается по умолчанию?
От: _NN_ www.nemerleweb.com
Дата: 17.09.21 14:59
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>Хм, а какой в этом может быть смысл? Где такое может пригодиться?


Сетевые протоколы. Как бы название структуры намекает
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[9]: Как вышло, что наложение предполагается по умолчанию?
От: B0FEE664  
Дата: 17.09.21 16:04
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

BFE>>Изначально речь шла про память, а не про регистры.

ЕМ>Чем регистры любого контроллера, отображенные на адресное пространство, отличаются от памяти с точки зрения программы?
Не знаю, никогда не работал с отображением.

ЕМ>>>Такое возможно даже на 8-разрядных архитектурах, если флаги в регистрах выставляются асинхронно.

BFE>>Насколько мне известно, на всех архитектурах все мне известные способы сводятся ровно к одному — к разнесению по времени операций чтения и записи.
ЕМ>Операции чтения и записи физически не могут быть одновременными — их разносит, как минимум, сама аппаратура. Или о чем Вы?
Во-первых, физически возможно сделать одновременное чтение и запись (стирание). Если не говорить о самой физике, то можно так: берём две ячейки и рассматриваем её как одну. Пишем в одну ячейку — читаем из другой, по окончании записи — перенаправляем следующие чтение на записанную ячейку, а запись — на прочитанную. Но я не об этом, а всё о том же, о синхронизации двух и более данных.

BFE>>А чем это в сути своей отличается от однопроцессорности?

ЕМ>А чем двухпроцессорная система, в которой параллельные потоки обмениваются данными через общую память, отличается от однопроцессорной, где поток обменивается данными с контроллером, фактически представляющим собой независимый процессор?

Вроде бы ничем.
И каждый день — без права на ошибку...
Re[11]: Как вышло, что наложение предполагается по умолчанию?
От: B0FEE664  
Дата: 17.09.21 16:15
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

BFE>>Так как нет гарантий, что операции чтения атомарны (даже для одного байта)

ЕМ>Где их нет?
В стандарте.

ЕМ>Для большинства конкретных архитектур они как раз есть.

Знаете почему? А потому, что многие не умеют в параллельность.

ЕМ>А задача сделать надежную программу для абстрактной, заранее неизвестной архитектуры, напоминает анекдот о сферической лошади в вакууме.

Только вот в отличии от анекдотов, в жизни, программы написанные по правилам стандарта проще изменять и работают они быстрее.

BFE>>если есть два значения и операции над ними атомарны, тогда при отображении эти значений в GUI нет никаких гарантий их согласованности.

ЕМ>Если обновление GUI не затрагивает его структуры (например, все отображается на одних и тех же местах), и это обновление происходит достаточно часто (хотя бы несколько раз в секунду), то и ладно. Ну, мелькнет иногда неправильное значение в одном из полей на долю секунды, и что с того? Не тот случай, чтобы заморачиваться со всеобщей атомарностью.

И это вы называете надёжностью?

BFE>>Скажем строка принимающая два значения "OK" или "КО" в GUI может отобразится как "OO", "OK", "KO" или "KK". Т.е. нет никакого смысла передавать более одного данного из потока в поток таким способом.

ЕМ>Может, смысла и нет, а я всю жизнь передаю, и отлично работает, ни разу не жаловались.

Хмм... Точно не жаловались? Вот возьмём, к примеру, известную бухгалтерскую программу Horizon...
И каждый день — без права на ошибку...
Re[7]: Как вышло, что наложение предполагается по умолчанию?
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 17.09.21 19:04
Оценка:
Здравствуйте, _NN_, Вы писали:

ЕМ>>Где такое может пригодиться?


_NN>Сетевые протоколы.


А такое точно будет работать хотя бы не медленнее, чем обычная структура с "местным" порядком байтов, с переворотом после после получения и перед отправкой? Я несколько раз пробовал баловаться в C/C++ с битовыми полями — код получается страшноватый. Для предельной экономии памяти годится, для быстродействия — уже нет.
Re[10]: Как вышло, что наложение предполагается по умолчанию?
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 17.09.21 19:12
Оценка:
Здравствуйте, B0FEE664, Вы писали:

ЕМ>>Чем регистры любого контроллера, отображенные на адресное пространство, отличаются от памяти с точки зрения программы?


BFE>Не знаю, никогда не работал с отображением.


В общем случае, программа вообще никак не может отличить обычную память от регистров, отображенных на АП. И там, и там при обращении выполняются стандартные магистральные циклы.

BFE>физически возможно сделать одновременное чтение и запись (стирание).


Понятно, что возможно, но это сделано фактически на какой-либо архитектуре, для которой есть компиляторы C/C++?

ЕМ>>А чем двухпроцессорная система, в которой параллельные потоки обмениваются данными через общую память, отличается от однопроцессорной, где поток обменивается данными с контроллером, фактически представляющим собой независимый процессор?


BFE>Вроде бы ничем.


Вот именно. Но и в однопроцессорных системах легко делается обмен данными с любым контроллером так, чтобы не возникало гонок, блокировок и прочего. Атомарность операций (кроме банальных чтения и записи) для этого не нужна.
Re[8]: Как вышло, что наложение предполагается по умолчанию?
От: _NN_ www.nemerleweb.com
Дата: 18.09.21 04:47
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>Здравствуйте, _NN_, Вы писали:


ЕМ>>>Где такое может пригодиться?


_NN>>Сетевые протоколы.


ЕМ>А такое точно будет работать хотя бы не медленнее, чем обычная структура с "местным" порядком байтов, с переворотом после после получения и перед отправкой? Я несколько раз пробовал баловаться в C/C++ с битовыми полями — код получается страшноватый. Для предельной экономии памяти годится, для быстродействия — уже нет.


Ну я уточнил, что хотел автор.
Конечно может ударить по производительности.
С другой стороны функции сокетов итак работают с сетевым порядком байтов и ничего делать для них не нужно.
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[12]: Как вышло, что наложение предполагается по умолчанию?
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 18.09.21 09:23
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>>>Так как нет гарантий, что операции чтения атомарны (даже для одного байта)

ЕМ>>Где их нет?
BFE>В стандарте.

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

ЕМ>>Для большинства конкретных архитектур они как раз есть.


BFE>Знаете почему? А потому, что многие не умеют в параллельность.


Да многие вообще не умеют ничего, кроме как записывать конструкции языка из справочника или подходящего примера. К сожалению, стандарт нынче делается прежде всего для них. Но подозреваю, что изучить тот же C++20 досконально, чтобы помнить каждую мелочь и писать абсолютно переносимые программы, таки будет сложнее, чем добиться удовлетворительной практической переносимости, пользуясь спецификациями 90-х.

BFE>программы написанные по правилам стандарта проще изменять


Только при условии всеобъемлющего знания стандарта, когда любой нюанс помнишь или навскидку, или можешь быстро и уверенно найти по тексту. Какая доля современных программистов так может?

BFE>и работают они быстрее.


На каком основании? Ряд ограничений стандарта, угрожающих UB при их нарушении, на большинстве архитектур фактически нет нужды соблюдать, и можно сделать более эффективный код.

ЕМ>>Если обновление GUI не затрагивает его структуры (например, все отображается на одних и тех же местах), и это обновление происходит достаточно часто (хотя бы несколько раз в секунду), то и ладно. Ну, мелькнет иногда неправильное значение в одном из полей на долю секунды, и что с того? Не тот случай, чтобы заморачиваться со всеобщей атомарностью.


BFE>И это вы называете надёжностью?


Конечно. Что здесь ненадежного? Махните быстро перед глазами любыми электронными часами, которые надежно работают годами без перерыва — вместо четких цифр и букв увидите мешанину. Махните карандашом или линейкой перед экраном монитора — с высокой вероятностью увидите не размытый сектор, а четкий "веер". У кого-то возникают сомнения в надежности такого монитора?

BFE>Точно не жаловались?


Мои — точно.

BFE>Вот возьмём, к примеру, известную бухгалтерскую программу Horizon...


Ну, я ее не делал, и вообще впервые о ней слышу.
Re[6]: Как вышло, что наложение предполагается по умолчанию?
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 19.09.21 06:23
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

N>>Задачи "вывести 1 в порт" стали 0.001% от всех задач. Основные это таки что-то очень высокоуровневое.


ЕМ>Да не в портах дело. Чем отличается типичный физик или инженер от типичного математика? У физика и инженера хорошо развито чувство адекватности, сообразности. Если установка, которую предполагается использовать мобильно, получается весом под сто тонн — у них автоматически срабатывает триггер, что это абсурдно. А у математика такого триггера нет: задача решена, и ладно.


Это потому ты так пишешь, что путаешь чистого математика с прикладным. Чистый действительно думает в терминах "задача решена, дальше не волнует". Прикладной ещё и понимает цену решения.
Задача выбора правильного подмножества прикладной математики для обучения на "инженера-программиста", как тут предложили, сложна, но решается. Типовой курс содержит, например, оценки скорости сходимости разных методов численного интегрирования. Это уже хотя бы намёк на то, что надо смотреть на количественные характеристики.

ЕМ>Вот у меня телефон 2016-го года на Qualcomm Snapdragon 650. Шесть ядер в среднем по полтора гигагерца. Google Services на нем изначально работали достаточно быстро. А сейчас, когда я тапаю на Update All в списке обновлений, проходит семь-восемь секунд до того, как кнопка Update All превратится в Cancel All. Все это время экран сохраняет прежний вид, и я даже не знаю, сработал мой тап, или нет. Восемь секунд, Карл! На полутора гигагерцах и шести ядрах! Что нужно курить, чтобы так сделать? Я не знаю. Это возможно лишь путем "последовательной записи конструкций языка, в итоге приводящих к решению поставленной задачи". Программированием в его исходном понимании это назвать невозможно.


Вполне возможно, что там вообще проблема не в программировании, а в управлении. Я не знаю конкретно тут причину. Но я знаю аналогичные случаи. Например, есть заявка решить проблему. Програмисты решают, уточняя в документации: "тут O(N^3), не расширяйте тут слишком сильно". Кто-то в менеджменте плюёт и даёт 1000 входных значений вместо ожидаемого предела 10. Кто виноват?
Ну да, можно сказать, что раз менеджмент был от программирования, то это программирование. Но IMHO это таки кривой менеджмент.

N>>и чтобы указание bigendian работало, как положено, на то, что version будет в старших битах байта по смещению 0


ЕМ>Хм, а какой в этом может быть смысл? Где такое может пригодиться?


Это был пример на заголовок IPv4 пакета. Там ровно эта проблема — порядок битов (даже не байтов). Сейчас из-за отсутствия таких определений приходится писать так:

struct iphdr
  {
#if __BYTE_ORDER == __LITTLE_ENDIAN
    unsigned int ihl:4;
    unsigned int version:4;
#elif __BYTE_ORDER == __BIG_ENDIAN
    unsigned int version:4;
    unsigned int ihl:4;
#else
# error "Please fix <bits/endian.h>"
#endif


ну и далее по тексту.

Мало того, в IPv6 ещё злобнее получилось — поле flow label занимает в BE нумерации биты 12-31 (не знаю, нафига им столько), и если смотреть по байтам или шекам, то на LE машине оно разорвано на два несвязанных куска.
The God is real, unless declared integer.
Re[6]: Как вышло, что наложение предполагается по умолчанию?
От: Коваленко Дмитрий Россия http://www.ibprovider.com
Дата: 19.09.21 06:26
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>Да не в портах дело. Чем отличается типичный физик или инженер от типичного математика? У физика и инженера хорошо развито чувство адекватности, сообразности. Если установка, которую предполагается использовать мобильно, получается весом под сто тонн — у них автоматически срабатывает триггер, что это абсурдно. А у математика такого триггера нет: задача решена, и ладно.


Оффтоп, конечно.

20 лет назад, когда я закончил ПММ, я плевался и думал "за каким ... я согласился загрузить эту огромную бесполезную массу знаний в свою голову". И с большим облегчением все забыл.

А сейчас вот как-то сам дошел до понимания, что таки математика это походу единственная стоящая вещь, в этом мире бардака и бестолковости.

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

Хотя, если взять систему управления сделок с недвижимостью, которую я спроектировал в начале нулевых — там походу было наоброт. Ресурсов было реально мало и надо было исхитрится так, чтобы сократить объем работ и таки суметь довести проект конца.

Возможно не последнюю роль сыграли навыки приобретенные при решении математических задач ... ну правда не в ВУЗе, а в школе. Был там у меня особо тяжелый период борьбы с собственной тупостью

UPD. И кстати. Сейчас когда обнаруживаю проблемы/нестыковки в окружении, с которым приходится работать, все чаще думаю "да пусть они в #овне утонут со своими 'реальными' задачами.".
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Отредактировано 19.09.2021 6:38 DDDX . Предыдущая версия . Еще …
Отредактировано 19.09.2021 6:27 DDDX . Предыдущая версия .
Re[8]: Как вышло, что наложение предполагается по умолчанию?
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 19.09.21 06:57
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

_NN>>Сетевые протоколы.


ЕМ>А такое точно будет работать хотя бы не медленнее, чем обычная структура с "местным" порядком байтов, с переворотом после после получения и перед отправкой?


Ты имеешь в виду то, что поле какого-то полного размера (2, 4, 8 байт) хранится постоянно в памяти в чужом порядке (обычно — в BE при машине в LE; обратный вариант крайне редок) и переворачивается при чтении или записи?

Последние лет 10 на x86 практически во всех процессорах есть инструкция MOVBE — для чтения/записи именно памяти. Ещё с 486-го была BSWAP над регистром. Поэтому тут оно происходит на полной скорости без задержки. Для ARM нужна дополнительная REV между регистрами, это затянет ну ещё один такт в самом тяжёлом случае (часто и без него). В общем, дёшево.

Но я имел в виду не столько оптимизацию или её отсутствие, сколько переносимость описания. И обрати внимание, что первая пара значений — в одном байте. Ты там вообще переворотом порядка байт ничего не добьёшься. Если не иметь таких тегов и не делать зависимости от дефайна — читать/писать можно только явными смещениями и масками. Да, работает. Но неудобно.

EM> Я несколько раз пробовал баловаться в C/C++ с битовыми полями — код получается страшноватый. Для предельной экономии памяти годится, для быстродействия — уже нет.


Может, это проблема MSVC. А ещё это проблема x86. Хороший пример — представление float:
typedef struct sfloat32 {
  unsigned significand : 23;
  unsigned exponent : 8;
  unsigned sign : 1;
} sfloat32;
sfloat32 insert_exponent(sfloat32 input, unsigned new_exponent) {
  input.exponent = new_exponent;
  return input;
}


Обычная сборка gcc9 для x86 (Unix конвенция, первый параметр в di):

insert_exponent:
        movzx   eax, sil
        and     edi, -2139095041
        sal     eax, 23
        or      eax, edi
        ret


ну не так страшно — сдвиг и маска. Хотя можно было оптимизировать до двух rol и копирования sil. А вот смотрим на ARM:

insert_exponent:
        bfi     w0, w1, 23, 8
        ret


ну да, работает только для константных позиций, но таких случаев реально >99.9%.

Не знаю, что ты там видел в MSVC, может, страшнее в разы. Но вообще по сравнению с прочими операциями над данными в этих полях — почти ерунда.
The God is real, unless declared integer.
Re[6]: Как вышло, что наложение предполагается по умолчанию?
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 19.09.21 07:17
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>>>volatile имеет смысл только на однопроцессорной одноядерной архитектуре

ЕМ>>Э-э-э... Когда железо меняет значение регистра в произвольные моменты времени — как это связано с количеством процессов/ядер, работающих с этим железом?
BFE>Вот, допустим, программа читает 32-х битное значение в переменную из регистра, прочитала первые два байта и тут железо меняет значение регистра, поэтому прочтение третьего и четвёртого байта будут взяты от уже изменённого значения. Всё ведь так и задумано? Да?

Для таких архитектур всегда есть гарантии от производителей, типа: "операции чтения и записи порциями по 1, 2, 4, 8 байт, выполняемые на соответствующих границах, атомарны".
Как именно это обеспечивает архитектура — её дело. В типичном варианте это достигается за счёт кэша. Но это не обязательно.

Гарантии атомарности чтения/записи у атомарных переменных (грубо говоря, atomic<T> в C++) уже основаны на этих гарантиях архитектуры, а не наоборот. (Но это не выполняется для более широких типов — там подложка может хоть мьютексами обеспечивать атомарность.)

И с volatile в компиляторе это никак не связано. volatile не создаёт атомарность — оно запрещает кэшировать чтение и запись подобной переменной на уровне самого компилятора.
The God is real, unless declared integer.
Re[9]: Как вышло, что наложение предполагается по умолчанию?
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 19.09.21 07:20
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

BFE>>Изначально речь шла про память, а не про регистры.


ЕМ>Чем регистры любого контроллера, отображенные на адресное пространство, отличаются от памяти с точки зрения программы?


На уровне C/C++ ты вообще отображённые на память регистры (если это те регистры процессора, в которые компилятор кладёт рабочие данные) не влазят в основную концепцию и с ними работать нельзя, если не понимаешь всех последствий.

ЕМ>>>Такое возможно даже на 8-разрядных архитектурах, если флаги в регистрах выставляются асинхронно.

BFE>>Насколько мне известно, на всех архитектурах все мне известные способы сводятся ровно к одному — к разнесению по времени операций чтения и записи.

ЕМ>Операции чтения и записи физически не могут быть одновременными — их разносит, как минимум, сама аппаратура. Или о чем Вы?


Ну может и не разнести, если, например, у регистра есть порт чтения и порт записи, и доступ идёт одновременно. Это тот случай, который был, например, с PIIX timer.

BFE>>А чем это в сути своей отличается от однопроцессорности?


ЕМ>А чем двухпроцессорная система, в которой параллельные потоки обмениваются данными через общую память, отличается от однопроцессорной, где поток обменивается данными с контроллером, фактически представляющим собой независимый процессор?


Тем, что нет причин делать синхронизацию в памяти? Или как? Тут сложно понять вопрос.
The God is real, unless declared integer.
Re[8]: Как вышло, что наложение предполагается по умолчанию?
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 19.09.21 07:34
Оценка: 3 (2)
Здравствуйте, B0FEE664, Вы писали:

ЕМ>>Такое возможно даже на 8-разрядных архитектурах, если флаги в регистрах выставляются асинхронно. Для борьбы с этим есть ряд способов, которые Вам должны быть известны.

BFE>Насколько мне известно, на всех архитектурах все мне известные способы сводятся ровно к одному — к разнесению по времени операций чтения и записи. А чем это в сути своей отличается от однопроцессорности?

Речь немного о другом, насколько я понимаю.
Вот в какой-то момент Intel ввёл в своих чипсетах PIIX timer (позже был назван ACPI-fast). Это 4 байта по некоторому адресу, которые значение счётчика с частотой 1/4 таймерного кварца (3579545.5 Гц), в коротком варианте валидны только 24 бита, в полном — 32.
Но на чтение из этого таймера они не поставили защёлку, а волна переворотов битов идёт медленно, поэтому возможны, например, такие ситуации:
— в какой-то момент значение 7 (0111 в двоичке)
— пришёл сигнал "добавить 1", пошла волна переворотов, младший бит перевернулся, следующий — ещё нет
— тут процессор читает таймер, видит значение 6 (0110)
— волна доходит дальше, в таймере 4 (0100)
— волна доходит дальше, в таймере 0 (0000)
— волна доходит дальше, в таймере 8 (1000), волна остановилась.

Соответственно, если процессор прочитал в неподходящий момент, он увидит явное "не то".
Защита чисто программная и выглядит так: читаем не один раз, а 3 подряд. Пусть прочли x1, x2, x3. Если x1 <= x2 <= x3, чтение было корректно и возвращаем x3. Иначе идём на следующий круг.

В следующем варианте "ACPI-safe" есть защёлка (дополнительный регистр, в который, в простейшем варианте, переписывается значение счётчика в противофазе — например, если инкремент происходит по фронту, то запись в защёлку — по спаду; возможно также делать пред-запись увеличенного значения). Там таких проблем нет. Какой вариант таймера доступен — читается в таблицах ACPI. В HPET защёлки декларированы изначально, в TSC — тоже.

Аналогичная проблема возникает, например, при чтении 64-битного значения двумя 32-битными операциями. Можно сделать так: прочитать дважды и сравнить две пары чисел, если где-то расхождение, то чтение было неатомарно, потому что кто-то влез посредине.
The God is real, unless declared integer.
Re[6]: Как вышло, что наложение предполагается по умолчанию?
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 19.09.21 07:39
Оценка:
Здравствуйте, B0FEE664, Вы писали:

ЕМ>>А еще может быть, что программист явно указал отсутствие наложение, а через месяц или год изменил алгоритм так, что наложение возникло, но квалификатор убрать забыл. На все такие варианты соломы не напасешься.

BFE>Это почему же нет? Нет квалификатора — нет проблемы.

Как раз проблема в том, что квалификатор restrict остался, когда не должен был оставаться.

Поймать такую проблему, да, сложно — только глубоким анализом кода.
The God is real, unless declared integer.
Re[12]: Как вышло, что наложение предполагается по умолчанию?
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 19.09.21 07:46
Оценка:
Здравствуйте, TailWind, Вы писали:

BFE>>>Так как нет гарантий, что операции чтения атомарны (даже для одного байта)


ЕМ>>Где их нет? Для большинства конкретных архитектур они как раз есть. А задача сделать надежную программу для абстрактной, заранее неизвестной архитектуры, напоминает анекдот о сферической лошади в вакууме.


TW>Про один байт можете быть совершенно спокойны


TW>Микросхема памяти имеет только один порт. Более того минимальная единица записи — 1 байт


TW>Писать и читать можно только по очереди, а не одновременно

TW>Поэтому никто не сможет изменить часть бит, пока вы читаете
TW>Никак не сможет получится, что вы считали байт, в котором часть бит от нового значения, а часть от старого
TW>Целостность байта нарушить не получится

Для обычной памяти — да, так. (На самом деле, стандартные модули DRAM давно уже оперируют порциями в 8 байт. Кэш в x86 — 64 байта. Так что тут и больше атомарность. Но — только по выровненным границам. Читать и писать двухбайтовое значение по адресам 63 и 64 — имеет в большинстве случаев законное право порваться на две независимые операции.)

Но вот для более хитрых объектов типа регистров ввода-вывода — я описал
Автор: netch80
Дата: 19.09.21
ситуацию, где по сути атомарность доступа — 1 бит, даже при чтении порцией в 32 бита. Это из реального железа, которое ещё должно быть доступно, и для процессора это таки данные в памяти (а не I/O пространстве).
The God is real, unless declared integer.
Re[12]: Как вышло, что наложение предполагается по умолчанию?
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 19.09.21 08:14
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>>>Так как нет гарантий, что операции чтения атомарны (даже для одного байта)

ЕМ>>Где их нет?
BFE>В стандарте.

ЕМ>>Для большинства конкретных архитектур они как раз есть.

BFE>Знаете почему? А потому, что многие не умеют в параллельность.

Такое впечатление, что вы на принципиальном уровне путаете требования уровня архитектуры и уровня языка.

На уровне архитектуры гарантии предоставляются для операций при определённых условиях (например, что это реальная память или что-то адекватно её имитирующее, операции определённого размера и соответственно выровнены). Требования синхронизации, где они возникают из одновременного доступа, OoO исполнения и т.п., чётко определены на уровне инструкций и их свойств.

На уровне уже языка типа C/C++, во-первых, вмешивается кэширование и реордеринг от компилятора (это то, против чего защищаются или volatile, или atomic_signal_fence). Во-вторых, гарантии упорядочения сведены к точкам синхронизации и операциям перед и после них, а ключевое понятие "synchronized with" определено вообще вокруг использования одного и того же объекта синхронизации. Там уже будут операции атомарны до байта или бита — не имеет значение (для хоть до 1/2 бита, если где-то такое есть). Битовые поля усугубляют картину — где они участвуют, про атомарность до байта уже нельзя говорить.

Рассматривать эти два контекста надо похожим образом, но обязательно раздельно.

ЕМ>>А задача сделать надежную программу для абстрактной, заранее неизвестной архитектуры, напоминает анекдот о сферической лошади в вакууме.

BFE>Только вот в отличии от анекдотов, в жизни, программы написанные по правилам стандарта проще изменять и работают они быстрее.

1) Не проще — см. проблему переполнения, вызванного изменением кода в другом углу огромного проекта.
2) Не "быстрее". Надёжнее — да. Но скорость как раз очень часто достигается отходом от жёстких рамок стандарта.

BFE>>>Скажем строка принимающая два значения "OK" или "КО" в GUI может отобразится как "OO", "OK", "KO" или "KK". Т.е. нет никакого смысла передавать более одного данного из потока в поток таким способом.

ЕМ>>Может, смысла и нет, а я всю жизнь передаю, и отлично работает, ни разу не жаловались.

BFE>Хмм... Точно не жаловались? Вот возьмём, к примеру, известную бухгалтерскую программу Horizon...


А что там?
The God is real, unless declared integer.
Re[9]: Как вышло, что наложение предполагается по умолчанию?
От: TailWind  
Дата: 19.09.21 15:07
Оценка:
Здравствуйте, netch80

N>Вот в какой-то момент Intel ввёл в своих чипсетах PIIX timer


Спасибо за интересную историю
Получил удовольствие соображая, как инженер Intel должен был сделать схему синхронизации чтобы таких проблем не было

N>В следующем варианте "ACPI-safe" есть защёлка (дополнительный регистр, в который, в простейшем варианте, переписывается значение счётчика в противофазе — например, если инкремент происходит по фронту, то запись в защёлку — по спаду;


Так эту проблему не решить

Тут фишка в том, что триггеры контроллера PCI работают от своего клока
А триггеры счётчика от своего

В результате, есть вероятность, что изменение значения счётчика попадёт точно под клок PCI, что переведёт его триггеры в бистабильное состояние (они начнут генерить (постоянно менять значения))
Re[10]: Как вышло, что наложение предполагается по умолчанию
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 19.09.21 18:05
Оценка:
Здравствуйте, TailWind, Вы писали:

N>>В следующем варианте "ACPI-safe" есть защёлка (дополнительный регистр, в который, в простейшем варианте, переписывается значение счётчика в противофазе — например, если инкремент происходит по фронту, то запись в защёлку — по спаду;


TW>Так эту проблему не решить

TW>Тут фишка в том, что триггеры контроллера PCI работают от своего клока
TW>А триггеры счётчика от своего

Да. Но это решаемо. Конечно, я упростил описание ситуации.

TW>В результате, есть вероятность, что изменение значения счётчика попадёт точно под клок PCI, что переведёт его триггеры в бистабильное состояние (они начнут генерить (постоянно менять значения))


Именно такое с бистабильностью — я не знаю, как достигнуть
Проблема понятна, и есть несколько вариантов решения. В случае значительного превышения одной частоты над другой — а тут именно так, у таймера, грубо говоря, 3.5 МГц, а у шины 33 МГц и выше — идёт синхронизация по большей частоте. Примерно так:
Три регистра: int_value, out_value, temp1 — все три — группы синхронных D-триггеров с записью по фронту.
1. В любой момент времени, когда в таймере (int_value) значение N, на выходе сумматора готово N+1. Синхронность тут ещё не нужна.
2. По фронту сигнала инкремента таймера взводится однобитовый флажок want_set и выход сумматора копируется в полноразмерный регистр temp1.
3. По комбинации фронта тактового сигнала шины и флажка обновления — значение temp1 сохраняется в out_value и want_set сбрасывается в 0.

Или чуть экономнее: temp1 удаляем, но делаем ещё один однобитовый флаг need_inc.
2. По фронту сигнала инкремента таймера взводится однобитовый флажок want_set.
3. По комбинации фронта тактового сигнала шины и want_set — выход сумматора записывается в out_value и взводится флажок need_inc; want_set сбрасывается в 0.
4. По любому перепаду тактового сигнала и need_inc — выход сумматора записывается в int_value, need_inc сбрасывается.

Повторюсь, для надёжности этого нужно, чтобы частота шины превышала частоту таймера (более чем в 2 раза), но тут это выполняется.

Вот если частоты близки или соотношение непредсказуемо — тогда суши вёсла Есть отдельная теория разработки полностью асинхронных и самосинхронных схем. Я знаю, кто в ней реально работает (хоть и на хобби), но сам не осилил.
The God is real, unless declared integer.
Отредактировано 19.09.2021 18:06 netch80 . Предыдущая версия .
Re[11]: Как вышло, что наложение предполагается по умолчанию
От: TailWind  
Дата: 19.09.21 19:13
Оценка:
N>Повторюсь, для надёжности этого нужно, чтобы частота шины превышала частоту таймера (более чем в 2 раза), но тут это выполняется.

Не обязательно

Синхронизировать 1 сигнал просто:
Нужно поставить ряд последовательных D триггеров на частоте счётчика
Когда с шины PCI приходит запрос на чтение, она изменяет состояние сигнала на входе первого триггера на обратное
Бистабильное состояние не сможет пройти через 3 последовательных триггера, в результате изменение увидит управляющая схема на частоте счётчика, как переход 1->0 или 0->1 (просто изменение значения)

Схема счётчика сделает копию значения счётчика в отдельный регистр. На частоте счётчика с этим проблем нет. Все биты будут точными
Через такую же последовательность D триггеров отправит уведомление шине PCI обратно, что сообщение получено (на частоте шины PCI)
Копия регистра не изменится за это время. И PCI сможет его спокойно считать без проблем с синхронизацией
Re[12]: Как вышло, что наложение предполагается по умолчанию
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 19.09.21 20:02
Оценка:
Здравствуйте, TailWind, Вы писали:

N>>Повторюсь, для надёжности этого нужно, чтобы частота шины превышала частоту таймера (более чем в 2 раза), но тут это выполняется.

TW>Не обязательно

Ну я говорил про те схемы. Они прямые и надёжные. Хотя про 2 раза перегнул: достаточно просто больше.

TW>Синхронизировать 1 сигнал просто:

TW>Нужно поставить ряд последовательных D триггеров на частоте счётчика
[...]

Я совсем не понял логику этого решения. Можно переформулировать?
По попыткам понять получилось что-то сильно более сложное, чем у меня.
Можно написать на условном Verilog/VHDL, разберу.
The God is real, unless declared integer.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.