Re[32]: ConcurrentDictionary vs reference type
От: Codealot Земля  
Дата: 27.02.22 17:02
Оценка: :))
Здравствуйте, Serginio1, Вы писали:

S> Ну ты хоть пример то приведи! А то все болтовня!


Я не виноват, что до тебя не доходит.
Вот например почитай https://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html

S> угу ссылка=new Конструктор() откуда она видна из другого процесса, а вот куда в итоге это ссылка записывается там и нужна синхронизация


Откуда передается ссылка — тоже. Нет никакого "после создания", Нео.

S>Это по сути то и есть ConcurrentDictionary. Но никаких проблем с интернированными строками я не слышал!


Там совершенно определенно делается лок при каждом вызове String.Intern, о чем и написано в твоей же ссылке. Ты читать вообще умеешь?
Ад пуст, все бесы здесь.
Re[33]: ConcurrentDictionary vs reference type
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 27.02.22 17:26
Оценка:
Здравствуйте, Codealot, Вы писали:

C>Там совершенно определенно делается лок при каждом вызове String.Intern, о чем и написано в твоей же ссылке. Ты читать вообще умеешь?

Так ConcurrentDictionary так же делается Lock только на цепоку с одинаковым hash % размер таблицы. Я же тебе код приводил, а ты смеялся.
http://rsdn.org/forum/dotnet/8199139.1
Автор: Serginio1
Дата: 19.02 22:54

Проблема как ты тут говорил не в ConcurrentDictionary, а в выделении памяти под строку.
Так вот проблем с конструктором строки нет!
Ты же говоришь, что нельзя применять ConcurrentDictionary с ссылочными типами, однако String.Intern прекрасно используют!
и солнце б утром не вставало, когда бы не было меня
Отредактировано 27.02.2022 18:02 Serginio1 . Предыдущая версия .
Re[33]: ConcurrentDictionary vs reference type
От: xpalex  
Дата: 28.02.22 05:41
Оценка: +4
Здравствуйте, Codealot, Вы писали:

C>Здравствуйте, Serginio1, Вы писали:


S>> Ну ты хоть пример то приведи! А то все болтовня!


C>Я не виноват, что до тебя не доходит.

C>Вот например почитай https://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html

Ну ты и некропост откопал. jdk5.

Для того что бы прочитать поле недоинициализированного объекта нужно что бы переупорядочилось store, store

thread 1:
// 1. выделение места на куче
load tmp, (result of allocation)
// 2. работа конструктора
store fieldValue, [tmp + offset]
// 3. возврат инициализированного объекта
store tmp, [objectRefVariable]

thread 2:
// 1. получение ссылки на объект
load [objectRefVariable]
// 2. получение ссылки/значения поля объекта.
load [objectRefVariable + offset]

если процессор переупорядочит шаг 2 и шаг 3 в thread 1, то thread 2 может прочитать неинициализированное поле.

Но если открыть описание memory model clr 2.0, то там явно указано, что reordering STORE,STORE запрещен. Т.е. рантайм берет на себя отвественность по генерации соотвествующего нативного кода при jit-е

Поэтому ты сначала сделай proof-of-concept, который сможет прочитать неиницилизировнное поле сконструированного объекта, а потом уже можешь пугать всех страшными багами в CLR.

А пока все выглядит так, что ты первый раз увидел, что DoubleCheckedLocking не работает (этой инфе лет 15 уже).
Re[14]: ConcurrentDictionary vs reference type
От: · Великобритания  
Дата: 28.02.22 10:16
Оценка:
Здравствуйте, xpalex, Вы писали:

X>Т.е. до спеки ты не добрался?


X>https://www.ecma-international.org/wp-content/uploads/ECMA-335_6th_edition_june_2012.pdf


X>

X>I.12.6.8 Other memory model issues
X>All memory allocated for static variables (other than those assigned RVAs within a PE file, see
X>Partition II) and objects shall be zeroed before they are made visible to any user code.
X>A conforming implementation of the CLI shall ensure that, even in a multi-threaded environment
X>and without proper user synchronization, objects are allocated in a manner that prevents
X>unauthorized memory access and prevents invalid operations from occurring. In particular, on
X>multiprocessor memory systems where explicit synchronization is required to ensure that all
X>relevant data structures are visible (for example, vtable pointers) the Execution Engine shall be
X>responsible for either enforcing this synchronization automatically or for converting errors due to
X>lack of synchronization into non-fatal, non-corrupting, user-visible exceptions.
X>It is explicitly not a requirement that a conforming implementation of the CLI guarantee that all
X>state updates performed within a constructor be uniformly visible before the constructor
X>completes. CIL generators can ensure this requirement themselves by inserting appropriate calls
X>to the memory barrier or volatile write instructions.

Бинго! Т.е. Codealot таки прав. Тут написано, что гарантируется только аллокация участка памяти и зануление, но не инициализация. А выполнение конструктора может быть и не visible.

В java есть такой тонкий момент, решается final-полями (или readonly в терминологии дотнета) и он явно описан в стандарте языка.
Вот в таком коде:
class FinalFieldExample { 
    final int x;
    int y; 

    public FinalFieldExample() {
        x = 3; 
        y = 4; 
    }

Значение y может быть 0 или 4 из другого потока, т.к. оно не final. А для x — гарантируется, что будет 3. Иными словами final создаёт барьер в компиляторе (т.е. без лишнего перформанс-проседания). Как такое решается в дотнете неясно. Судья по обсуждению тут — пока что лишь добавлением недокументированных барьеров во всякие рандомные места.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[15]: ConcurrentDictionary vs reference type
От: samius Россия http://sams-tricks.blogspot.com
Дата: 28.02.22 10:35
Оценка:
Здравствуйте, ·, Вы писали:

·>Бинго! Т.е. Codealot таки прав. Тут написано, что гарантируется только аллокация участка памяти и зануление, но не инициализация. А выполнение конструктора может быть и не visible.


Все-таки тут написано что
1) за обнуление отвечает непосредственно CLI.
2) То, что будет видно все состояние объекта, выполненное в конструкторе — не является требованием непосредственно к CLI, т.к. это требование могут обеспечивать CIL генераторы.
Re[16]: ConcurrentDictionary vs reference type
От: · Великобритания  
Дата: 28.02.22 11:03
Оценка:
Здравствуйте, samius, Вы писали:

S>·>Бинго! Т.е. Codealot таки прав. Тут написано, что гарантируется только аллокация участка памяти и зануление, но не инициализация. А выполнение конструктора может быть и не visible.

S>Все-таки тут написано что
S>1) за обнуление отвечает непосредственно CLI.
+1. Только это не относится к вопросу.

S>2) То, что будет видно все состояние объекта, выполненное в конструкторе — не является требованием непосредственно к CLI, т.к. это требование могут обеспечивать CIL генераторы.

Эээ.. Не очень ясно. Тут написано "can", т.е. какой-то кодогенератор _может_ вставлять барьеры, видимо в зависимости от семантики самого ЯП и данного куска кода. Но ведь может-то и не вставлять! Т.е. эта цитата вообще нерелевантна к оригинальному вопросу, никак на него не отвечает.
Хочется увидеть ссылку на спеку, что c# генератор таки обязуется делать операции в конструкторе visible другим тредам. Ещё интересен такой кусок кода:
class Example {
  int value;
  
  public Example(IObserver observer) {
    this.value = 42;
    observer.sendToAnotherThread(this);// вот тут другой тред точно увидит 42 или может быть и 0??
  }
}


В случае java и final поля — гарантия есть по стандарту.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[17]: ConcurrentDictionary vs reference type
От: samius Россия http://sams-tricks.blogspot.com
Дата: 28.02.22 11:23
Оценка:
Здравствуйте, ·, Вы писали:

·>Здравствуйте, samius, Вы писали:


S>>2) То, что будет видно все состояние объекта, выполненное в конструкторе — не является требованием непосредственно к CLI, т.к. это требование могут обеспечивать CIL генераторы.

·>Эээ.. Не очень ясно. Тут написано "can", т.е. какой-то кодогенератор _может_ вставлять барьеры, видимо в зависимости от семантики самого ЯП и данного куска кода. Но ведь может-то и не вставлять! Т.е. эта цитата вообще нерелевантна к оригинальному вопросу, никак на него не отвечает.
·>Хочется увидеть ссылку на спеку, что c# генератор таки обязуется делать операции в конструкторе visible другим тредам. Ещё интересен такой кусок кода:
Разумеется, CIL генератор не обязан это делать, если с этим справляется CLI или железо этого не требует. Эта спека все-таки про модель памяти, а не про CIL генератор.
·>
·>class Example {
·>  int value;
  
·>  public Example(IObserver observer) {
·>    this.value = 42;
·>    observer.sendToAnotherThread(this);// вот тут другой тред точно увидит 42 или может быть и 0??
·>  }
·>}
·>

Из данной цитаты вообще ничего не следует в отношении данного примера. Т.е. конструктор еще не отработал формально и мы не должны делать выводов о видимости состояния кроме как о том, что обнулено оно будет железно. Но sendToAnotherThread не имеет магического способа заставить другой поток работать с этими данными по ссылке. Или этой магии придется обращаться уже к неким функциям управления потоками, а уж они обеспечат видимость измененного в конструкторе состояния другим потокам. В любом случае this придется опубликовать.
Re[18]: ConcurrentDictionary vs reference type
От: · Великобритания  
Дата: 28.02.22 12:25
Оценка:
Здравствуйте, samius, Вы писали:

S>>>2) То, что будет видно все состояние объекта, выполненное в конструкторе — не является требованием непосредственно к CLI, т.к. это требование могут обеспечивать CIL генераторы.

S>·>Эээ.. Не очень ясно. Тут написано "can", т.е. какой-то кодогенератор _может_ вставлять барьеры, видимо в зависимости от семантики самого ЯП и данного куска кода. Но ведь может-то и не вставлять! Т.е. эта цитата вообще нерелевантна к оригинальному вопросу, никак на него не отвечает.
S>·>Хочется увидеть ссылку на спеку, что c# генератор таки обязуется делать операции в конструкторе visible другим тредам. Ещё интересен такой кусок кода:
S>Разумеется, CIL генератор не обязан это делать, если с этим справляется CLI или железо этого не требует. Эта спека все-таки про модель памяти, а не про CIL генератор.
Оригинальный вопрос был именно про генератор c#. Причём тут CLI и обнуление памяти — неясно. Зачем привели эту цитату — неясно.

S>Из данной цитаты вообще ничего не следует в отношении данного примера. Т.е. конструктор еще не отработал формально и мы не должны делать выводов о видимости состояния кроме как о том, что обнулено оно будет железно.

Ок. Хорошо, но уже лучше. А вот такой пример тоже работает так же? Если он работает как-то иначе, плиз ссылку в стандарт.

class Example {
  int value;
  
  public Example() {
    this.value = 42;
  }
}
...
observer.sendToAnotherThread(new Example());// вот тут другой тред точно увидит 42 или может быть и 0??


S>Но sendToAnotherThread не имеет магического способа заставить другой поток работать с этими данными по ссылке. Или этой магии придется обращаться уже к неким функциям управления потоками, а уж они обеспечат видимость измененного в конструкторе состояния другим потокам. В любом случае this придется опубликовать.

_заставить_ одно дело. Другое дело, что ссылка может быть передана и без _заставить_ (например через запись-чтение non-volatile переменной), и другой тред неожиданно увидит 0. А _заставление_ произойдёт немного позже явным барьером, например. Иными словами, барьер обязует лишь то, что изменение будет увиденно, но никто не гарантирует, что если барьера (ещё) нет, то и никто не увидит.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[19]: ConcurrentDictionary vs reference type
От: samius Россия http://sams-tricks.blogspot.com
Дата: 28.02.22 13:10
Оценка: +2
Здравствуйте, ·, Вы писали:

·>Здравствуйте, samius, Вы писали:


S>>Разумеется, CIL генератор не обязан это делать, если с этим справляется CLI или железо этого не требует. Эта спека все-таки про модель памяти, а не про CIL генератор.

·>Оригинальный вопрос был именно про генератор c#. Причём тут CLI и обнуление памяти — неясно. Зачем привели эту цитату — неясно.
Оригинальный вопрос был про то, нужен ли бубен при работе с ConcurrentDictionary. Генератор там ну никак не упоминался, если, конечно он не назван бубном. Но вряд ли.

S>>Из данной цитаты вообще ничего не следует в отношении данного примера. Т.е. конструктор еще не отработал формально и мы не должны делать выводов о видимости состояния кроме как о том, что обнулено оно будет железно.

·>Ок. Хорошо, но уже лучше. А вот такой пример тоже работает так же? Если он работает как-то иначе, плиз ссылку в стандарт.

·>
·>class Example {
·>  int value;
  
·>  public Example() {
·>    this.value = 42;
·>  }
·>}
·>...
·>observer.sendToAnotherThread(new Example());// вот тут другой тред точно увидит 42 или может быть и 0??
·>

я это вижу таким образом, что либо conforming implementation of the CLI, либо CIL generators должны нам обеспечить 42.

S>>Но sendToAnotherThread не имеет магического способа заставить другой поток работать с этими данными по ссылке. Или этой магии придется обращаться уже к неким функциям управления потоками, а уж они обеспечат видимость измененного в конструкторе состояния другим потокам. В любом случае this придется опубликовать.

·>_заставить_ одно дело. Другое дело, что ссылка может быть передана и без _заставить_ (например через запись-чтение non-volatile переменной), и другой тред неожиданно увидит 0. А _заставление_ произойдёт немного позже явным барьером, например. Иными словами, барьер обязует лишь то, что изменение будет увиденно, но никто не гарантирует, что если барьера (ещё) нет, то и никто не увидит.
Если конструктор отработал, то ссылаемся на реализацию CLI или генераторов. Если ссылка протекла в другой тред до завершения конструктора — то как минимум, на этот текст мы опираться не можем. Но в оригинале же речь о том, можно ли без бубна класть объект в ConcurrentDictionary и потом доставать его оттуда, не боясь хтонических ужасов. В итоге, если мы в словарь положим каким-то чудом протекшую ссылку на объект, чей конструктор еще не выполнен, то надеяться остается лишь на реализацию словаря. Однако, хтонический ужас уже в том, что мы в словарь пытаемся положить ссылку на объект, чей конструктор еще не выполнился. А значит, никто не отвечает не то, что бы за барьер памяти, а тупо состояние объекта может быть незаполнено еще тем потоком, который выполняет конструктор. Т.е. достать из словаря мы имеем право тоже объект, чей конструктор еще не выполнился.

Так причем тут словарь вообще и документация к нему? Даже если мы руками выполним барьер памяти, это не приведет к принудительному завершению конструктора в другом треде и заполнению полей объекта.
Re[20]: ConcurrentDictionary vs reference type
От: · Великобритания  
Дата: 28.02.22 13:23
Оценка:
Здравствуйте, samius, Вы писали:

S>>>Разумеется, CIL генератор не обязан это делать, если с этим справляется CLI или железо этого не требует. Эта спека все-таки про модель памяти, а не про CIL генератор.

S>·>Оригинальный вопрос был именно про генератор c#. Причём тут CLI и обнуление памяти — неясно. Зачем привели эту цитату — неясно.
S>Оригинальный вопрос был про то, нужен ли бубен при работе с ConcurrentDictionary. Генератор там ну никак не упоминался, если, конечно он не назван бубном. Но вряд ли.
ConcurrentDictionary это лишь один из способов передачи объектов между тредами.

S>я это вижу таким образом, что либо conforming implementation of the CLI, либо CIL generators должны нам обеспечить 42.

А я не вижу. CLI должен обеспечить только 0 (он отвечает за zeroeing и всё). А про CIL написано, что лишь _может_, "должен" не написано, как ты заявляешь. Подтверди свою т.з. документацией.

S>Так причем тут словарь вообще и документация к нему? Даже если мы руками выполним барьер памяти, это не приведет к принудительному завершению конструктора в другом треде и заполнению полей объекта.

Э.. Ну да. Вопрос в другом. Вопрос в том, что в спеке c# делает конструкторы чем-то особенным? Чем sendToAnotherThread внутри конструктора отличается от sendToAnotherThread снаружи конструктора?
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[21]: ConcurrentDictionary vs reference type
От: samius Россия http://sams-tricks.blogspot.com
Дата: 28.02.22 14:11
Оценка:
Здравствуйте, ·, Вы писали:

·>Здравствуйте, samius, Вы писали:


S>>Оригинальный вопрос был про то, нужен ли бубен при работе с ConcurrentDictionary. Генератор там ну никак не упоминался, если, конечно он не назван бубном. Но вряд ли.

·>ConcurrentDictionary это лишь один из способов передачи объектов между тредами.
не поспоришь

S>>я это вижу таким образом, что либо conforming implementation of the CLI, либо CIL generators должны нам обеспечить 42.

·>А я не вижу. CLI должен обеспечить только 0 (он отвечает за zeroeing и всё). А про CIL написано, что лишь _может_, "должен" не написано, как ты заявляешь. Подтверди свою т.з. документацией.
Верно, и про CIL написано что может. То, что он должен — не написано, т.к. может и CLI за это отвечать.

S>>Так причем тут словарь вообще и документация к нему? Даже если мы руками выполним барьер памяти, это не приведет к принудительному завершению конструктора в другом треде и заполнению полей объекта.

·>Э.. Ну да. Вопрос в другом. Вопрос в том, что в спеке c# делает конструкторы чем-то особенным? Чем sendToAnotherThread внутри конструктора отличается от sendToAnotherThread снаружи конструктора?
C#, на сколько я помню, тут вообще не при чем. И если даже мы найдем в спеке языка что-то, то вопрос о том, будет ли это исполняться для VB.NET или F#, или еще какого-то дотнет языка — останется открыт. А ConcurrentDictionary он вне языка. CLI и CIL, собственно, тоже. Поэтому, я бы C# в эту тему не впутывал бы.
Re[22]: ConcurrentDictionary vs reference type
От: · Великобритания  
Дата: 28.02.22 14:30
Оценка:
Здравствуйте, samius, Вы писали:

S>>>Оригинальный вопрос был про то, нужен ли бубен при работе с ConcurrentDictionary. Генератор там ну никак не упоминался, если, конечно он не назван бубном. Но вряд ли.

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

S>>>я это вижу таким образом, что либо conforming implementation of the CLI, либо CIL generators должны нам обеспечить 42.

S>·>А я не вижу. CLI должен обеспечить только 0 (он отвечает за zeroeing и всё). А про CIL написано, что лишь _может_, "должен" не написано, как ты заявляешь. Подтверди свою т.з. документацией.
S>Верно, и про CIL написано что может. То, что он должен — не написано, т.к. может и CLI за это отвечать.
Да ё-моё, ты всё смешал. Про CIL написано о конструкторах, а про CLI написано о zeroeing. Т.е. из цитаты следует, что 0 будет точно (т.е. не будет случайных значений из неинициалированного куска памяти как бывает в Плюсах, например), но гарантии что будет 42 я в упор не вижу.

S>>>Так причем тут словарь вообще и документация к нему? Даже если мы руками выполним барьер памяти, это не приведет к принудительному завершению конструктора в другом треде и заполнению полей объекта.

S>·>Э.. Ну да. Вопрос в другом. Вопрос в том, что в спеке c# делает конструкторы чем-то особенным? Чем sendToAnotherThread внутри конструктора отличается от sendToAnotherThread снаружи конструктора?
S>C#, на сколько я помню, тут вообще не при чем. И если даже мы найдем в спеке языка что-то, то вопрос о том, будет ли это исполняться для VB.NET или F#, или еще какого-то дотнет языка — останется открыт.
Не смешивай consructors и zeroeing. C# тут притом что он обеспечивает конструкторы. А CIL обеспечивает аллокацию памяти и инициализацию её нулями.

S>А ConcurrentDictionary он вне языка. CLI и CIL, собственно, тоже. Поэтому, я бы C# в эту тему не впутывал бы.

Да, конкретно ConcurrentDictionary тут и не причём, он тут лишь как средство межтредной передачи. Да и не относится он к c#, он относится к стандартной библиотеке, а не к языку.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Отредактировано 28.02.2022 14:31 · . Предыдущая версия .
Re[23]: ConcurrentDictionary vs reference type
От: samius Россия http://sams-tricks.blogspot.com
Дата: 28.02.22 14:50
Оценка:
Здравствуйте, ·, Вы писали:

·>Здравствуйте, samius, Вы писали:


S>>не поспоришь

·>Плюс идея в том, что наличие барьеров в текущей имплементации ConcurrentDictionary может маскировать проблему. Что-нибудь может измениться внезапно (оставаясь в рамках документированного контракта ConcurrentDictionary), и полезут интересные баги.
И это не проблема ConcurrentDictionary и его контракта, т.к. у нас есть несколько Concurrent* классов, да и не только они.

·>Да ё-моё, ты всё смешал. Про CIL написано о конструкторах, а про CLI написано о zeroeing. Т.е. из цитаты следует, что 0 будет точно (т.е. не будет случайных значений из неинициалированного куска памяти как бывает в Плюсах, например), но гарантии что будет 42 я в упор не вижу.

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

S>>C#, на сколько я помню, тут вообще не при чем. И если даже мы найдем в спеке языка что-то, то вопрос о том, будет ли это исполняться для VB.NET или F#, или еще какого-то дотнет языка — останется открыт.

·>Не смешивай consructors и zeroeing. C# тут притом что он обеспечивает конструкторы. А CIL обеспечивает аллокацию памяти и инициализацию её нулями.
C# тут лишний, т.к. конструкторы бывают и без C#. В C++/CLI или даже просто в IL тоже есть конструкторы.

S>>А ConcurrentDictionary он вне языка. CLI и CIL, собственно, тоже. Поэтому, я бы C# в эту тему не впутывал бы.

·>Да, конкретно ConcurrentDictionary тут и не причём, он тут лишь как средство межтредной передачи. Да и не относится он к c#, он относится к стандартной библиотеке, а не к языку.
Re[24]: ConcurrentDictionary vs reference type
От: · Великобритания  
Дата: 28.02.22 16:29
Оценка: 4 (1)
Здравствуйте, samius, Вы писали:

S>>>не поспоришь

S>·>Плюс идея в том, что наличие барьеров в текущей имплементации ConcurrentDictionary может маскировать проблему. Что-нибудь может измениться внезапно (оставаясь в рамках документированного контракта ConcurrentDictionary), и полезут интересные баги.
S>И это не проблема ConcurrentDictionary и его контракта, т.к. у нас есть несколько Concurrent* классов, да и не только они.
Перечитай что я написал. Я ничего не говорил о том, что в ConcurrentDictionary есть проблема. Я говорил, что проблема может быть в коде, который использует ConcurrentDictionary, но эта проблема не видна, т.к. замаскирована барьерами в ConcurrentDictionary. Т.е. присваивание в конструкторе будет работать правильно только с конкретной имплементацией платформы. Собственно, so тоже согласен, что это implementation defined:

It is not specified in ECMA standard, it is just the microsoft implementation of the CLR gives this guarantee. If you run this code in either CLR 1.0 or any other implementation of CLR, your code is likely to break.

Собственно, как я понял, Codealot это и имел в виду.

И сделано это ценой потери перформанса:

unfortunate that synchronization cost caused by this CLR2.0 guarantee is payed by all code, yet typically only <1% of code deals with threading at all.


S>·>Да ё-моё, ты всё смешал. Про CIL написано о конструкторах, а про CLI написано о zeroeing. Т.е. из цитаты следует, что 0 будет точно (т.е. не будет случайных значений из неинициалированного куска памяти как бывает в Плюсах, например), но гарантии что будет 42 я в упор не вижу.

S>Так в описании CLI тебе эту гарантию и не дают, но указывают, что этим могут заниматься сущности за пределом ответственности CLI. При необходимости, разумеется.
Твоё заявление: "CIL generators должны нам обеспечить 42", неверно, это ошибка. Ничего в стандарте 42 не обеспечивает, только текущие детали имплементации платформы от microsoft это обещают.

S>>>C#, на сколько я помню, тут вообще не при чем. И если даже мы найдем в спеке языка что-то, то вопрос о том, будет ли это исполняться для VB.NET или F#, или еще какого-то дотнет языка — останется открыт.

S>·>Не смешивай consructors и zeroeing. C# тут притом что он обеспечивает конструкторы. А CIL обеспечивает аллокацию памяти и инициализацию её нулями.
S>C# тут лишний, т.к. конструкторы бывают и без C#. В C++/CLI или даже просто в IL тоже есть конструкторы.
Ну и? Кто из них должен обеспечить 42 по-твоему?!
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Отредактировано 28.02.2022 16:34 · . Предыдущая версия .
Re[25]: ConcurrentDictionary vs reference type
От: samius Россия http://sams-tricks.blogspot.com
Дата: 28.02.22 16:44
Оценка: -1
Здравствуйте, ·, Вы писали:

·>Здравствуйте, samius, Вы писали:


S>>И это не проблема ConcurrentDictionary и его контракта, т.к. у нас есть несколько Concurrent* классов, да и не только они.

·>Перечитай что я написал. Я ничего не говорил о том, что в ConcurrentDictionary есть проблема. Я говорил, что проблема может быть в коде, который использует ConcurrentDictionary, но эта проблема не видна, т.к. замаскирована барьерами в ConcurrentDictionary. Т.е. присваивание в конструкторе будет работать правильно только с конкретной имплементацией платформы.
Извини, но мы тут про корректную имплементацию платформы и говорим. Если тебе нужна некорректная имплементация, то ты ошибся форумом, кмк. Не хотел обидеть, если что.

.>Собственно, so тоже согласен, что это implementation defined:

·>

It is not specified in ECMA standard, it is just the microsoft implementation of the CLR gives this guarantee. If you run this code in either CLR 1.0 or any other implementation of CLR, your code is likely to break.

·>Собственно, как я понял, Codealot это и имел в виду.
Ну так в рамках CLR 1.0 ему придется отказаться от ConcurrentDictionary вобоще. Не заведется, т.к. там нужен 2.0 минимум, хотя бы потому, что генерик. И с любой other implementation or CLR следовало бы уточнить для начала это, а не называть всех кретинами.

·>И сделано это ценой потери перформанса:

·>

unfortunate that synchronization cost caused by this CLR2.0 guarantee is payed by all code, yet typically only <1% of code deals with threading at all.

и много ли потеряли?

S>>Так в описании CLI тебе эту гарантию и не дают, но указывают, что этим могут заниматься сущности за пределом ответственности CLI. При необходимости, разумеется.

·>Твоё заявление: "CIL generators должны нам обеспечить 42", неверно, это ошибка. Ничего в стандарте 42 не обеспечивает, только текущие детали имплементации платформы от microsoft это обещают.
Не ничего не обеспечивает, а не назван конкретный механизм, обеспечивающий это.

S>>·>Не смешивай consructors и zeroeing. C# тут притом что он обеспечивает конструкторы. А CIL обеспечивает аллокацию памяти и инициализацию её нулями.

S>>C# тут лишний, т.к. конструкторы бывают и без C#. В C++/CLI или даже просто в IL тоже есть конструкторы.
·>Ну и? Кто из них должен обеспечить 42 по-твоему?!
Точно не уровень языка. CLI или CIL генератор.
Re[26]: ConcurrentDictionary vs reference type
От: · Великобритания  
Дата: 28.02.22 18:48
Оценка:
Здравствуйте, samius, Вы писали:

S>·>Перечитай что я написал. Я ничего не говорил о том, что в ConcurrentDictionary есть проблема. Я говорил, что проблема может быть в коде, который использует ConcurrentDictionary, но эта проблема не видна, т.к. замаскирована барьерами в ConcurrentDictionary. Т.е. присваивание в конструкторе будет работать правильно только с конкретной имплементацией платформы.

S>Извини, но мы тут про корректную имплементацию платформы и говорим. Если тебе нужна некорректная имплементация, то ты ошибся форумом, кмк. Не хотел обидеть, если что.
Я написал "конкретную", а ты читаешь "корректную". Перечитай, что я пишу. А теперь ещё раз внимательно, прежде чем в очередной раз ответить невпопад.

.>>Собственно, so тоже согласен, что это implementation defined:

S>·>

It is not specified in ECMA standard, it is just the microsoft implementation of the CLR gives this guarantee. If you run this code in either CLR 1.0 or any other implementation of CLR, your code is likely to break.

S>·>Собственно, как я понял, Codealot это и имел в виду.
S>Ну так в рамках CLR 1.0 ему придется отказаться от ConcurrentDictionary вобоще. Не заведется, т.к. там нужен 2.0 минимум, хотя бы потому, что генерик. И с любой other implementation or CLR следовало бы уточнить для начала это, а не называть всех кретинами.
Стиль его общения, конечно, не очень, но это не отменяет проблему.

S>·>И сделано это ценой потери перформанса:

S>·>

unfortunate that synchronization cost caused by this CLR2.0 guarantee is payed by all code, yet typically only <1% of code deals with threading at all.

S>и много ли потеряли?
Это другой вопрос. Я не знаю. Думаю, от аппаратной платформы зависит.

S>>>Так в описании CLI тебе эту гарантию и не дают, но указывают, что этим могут заниматься сущности за пределом ответственности CLI. При необходимости, разумеется.

S>·>Твоё заявление: "CIL generators должны нам обеспечить 42", неверно, это ошибка. Ничего в стандарте 42 не обеспечивает, только текущие детали имплементации платформы от microsoft это обещают.
S>Не ничего не обеспечивает, а не назван конкретный механизм, обеспечивающий это.
Я вообще не вижу, что там названы вообще хоть какие-то конкретные механизмы, этого в стандарте и не должно быть. Главное то, что в стандарте не написано, что этот механизм должен существовать.

S>>>·>Не смешивай consructors и zeroeing. C# тут притом что он обеспечивает конструкторы. А CIL обеспечивает аллокацию памяти и инициализацию её нулями.

S>>>C# тут лишний, т.к. конструкторы бывают и без C#. В C++/CLI или даже просто в IL тоже есть конструкторы.
S>·>Ну и? Кто из них должен обеспечить 42 по-твоему?!
S>Точно не уровень языка. CLI или CIL генератор.
Может я точно не знаю, но как я понимаю, CIL generator это такая штука, которая из c# генерит IL-инструкции. И то какие инструкции будут сгенерированы (в данном случае нас интересуют барьеры), определяются исходным кодом и семантикой c#.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[27]: ConcurrentDictionary vs reference type
От: samius Россия http://sams-tricks.blogspot.com
Дата: 28.02.22 20:26
Оценка: +1 -1
Здравствуйте, ·, Вы писали:

·>Здравствуйте, samius, Вы писали:


S>>·>Перечитай что я написал. Я ничего не говорил о том, что в ConcurrentDictionary есть проблема. Я говорил, что проблема может быть в коде, который использует ConcurrentDictionary, но эта проблема не видна, т.к. замаскирована барьерами в ConcurrentDictionary. Т.е. присваивание в конструкторе будет работать правильно только с конкретной имплементацией платформы.

·>Я написал "конкретную", а ты читаешь "корректную". Перечитай, что я пишу. А теперь ещё раз внимательно, прежде чем в очередной раз ответить невпопад.
Прости, виноват, невнимателен. Конкретная имплементация... Хорошо, пусть будет конкретная. Но когда будет еще одна конкретная имплементация, то целью второй имплементации будет повторение поведения первой конкретной, там где это возможно. А где невозможно — вот уж там надо будет писать на каждом углу и заборе, что что-то работает не так, как у конкретной, которая уже есть и к которой все привыкли за почти 20 лет (CLR 2.0 и последующие).

S>>Ну так в рамках CLR 1.0 ему придется отказаться от ConcurrentDictionary вобоще. Не заведется, т.к. там нужен 2.0 минимум, хотя бы потому, что генерик. И с любой other implementation or CLR следовало бы уточнить для начала это, а не называть всех кретинами.

·>Стиль его общения, конечно, не очень, но это не отменяет проблему.
А есть ли проблема? У нас есть конкретная платформа, в рамках которой все работает (пока не приведен код, демонстрирующий обратное). И нет другой конкретной платформы, где бы это не работало.

S>>и много ли потеряли?

·>Это другой вопрос. Я не знаю. Думаю, от аппаратной платформы зависит.
наверняка. Но не думаю, что это проблема. Т.е. проблема, конечно. Но ее решение может быть в чем? Вводить инструкции для разного железа и заставлять их учить всех, кто пишет на дотнете, но даже у кого нет и не будет такого железа, которое потребует знания специфики?

S>>Не ничего не обеспечивает, а не назван конкретный механизм, обеспечивающий это.

·>Я вообще не вижу, что там названы вообще хоть какие-то конкретные механизмы, этого в стандарте и не должно быть. Главное то, что в стандарте не написано, что этот механизм должен существовать.
Он упомянут. И названы два возможных места, где он может быть реализован. Возможно, есть еще места, но в голову не приходит, где это могло бы еще быть реализовано так, что бы мог работать общий код на IL и выше.
Я понимаю, тебя смущает что не написано, что 42 обязано быть. Меня тоже, но это уже как бы ложится на плечи тех ребят, которые будут делать другую конкретную имплементацию. Это, и наверное еще много чего другого, о чем тут не говорили. Но и не проси примеры. Я просто предполагаю.

S>>Точно не уровень языка. CLI или CIL генератор.

·>Может я точно не знаю, но как я понимаю, CIL generator это такая штука, которая из c# генерит IL-инструкции. И то какие инструкции будут сгенерированы (в данном случае нас интересуют барьеры), определяются исходным кодом и семантикой c#.
Вообще-то я был уверен что CIL генератор это что-то вроде NGen-а, но NGen — специфичен для конкретной платформы и его в стандарте постеснялись указать явно. Вот уж точно стандарт CLI не должен ссылаться на конкретные языки выше IL уровнем и их отображение в CIL. Кстати, этим занимаются просто компиляторы. Компилятор C#, F#, VB и т.п. И так уже много лет, все к этому привыкли. Может быть с рослином что-то поменялось, но текст, который мы пытаемся осилить — старше рослина. Найти, что конкретно подразумевается под CIL generator в том тексте — не осилил. Сложный день был.
Re[34]: ConcurrentDictionary vs reference type
От: Codealot Земля  
Дата: 07.03.22 19:51
Оценка:
Здравствуйте, Serginio1, Вы писали:

S> Так ConcurrentDictionary так же делается Lock только на цепоку с одинаковым hash % размер таблицы. Я же тебе код приводил, а ты смеялся.


Если делать lock на каждую операцию с коллекцией, то производительность будет пробивать днище. Так что, очевидно, там это не делается.

S> Ты же говоришь, что нельзя применять ConcurrentDictionary с ссылочными типами, однако String.Intern прекрасно используют!


Нет, я ничего подобного не говорил. Если у ConcurrentDictionary есть гарантии по наличию барьера памяти при добавлении объектов, то проблем с неизменяемыми объектами нет. А вот если бы таких гарантий не было, как заявлял
Автор: samius
Дата: 19.02 01:40
samius, то проблемы несомненно были бы.
Ад пуст, все бесы здесь.
Re[34]: ConcurrentDictionary vs reference type
От: Codealot Земля  
Дата: 07.03.22 19:51
Оценка:
Здравствуйте, xpalex, Вы писали:

X>Но если открыть описание memory model clr 2.0, то там явно указано, что reordering STORE,STORE запрещен. Т.е. рантайм берет на себя отвественность по генерации соотвествующего нативного кода при jit-е


А LOAD, LOAD разрешен. Как и LOAD, STORE. Так что без разницы.
Вот тут написано вполне буквально:
https://docs.microsoft.com/en-us/archive/msdn-magazine/2013/january/csharp-the-csharp-memory-model-in-theory-and-practice-part-2

As an example, consider this method:
XML

void Init() {
_data = 42;
_initialized = true;
}

If _data and _initialized are ordinary (that is, non-volatile) fields, the compiler and the processor are allowed to reorder the operations so that Init executes as if it were written like this:
XML

void Init() {
_initialized = true;
_data = 42;
}


X>Поэтому ты сначала сделай proof-of-concept, который сможет прочитать неиницилизировнное поле сконструированного объекта


Если бы ты хоть немного понимал о чем говоришь, то знал бы, насколько трудно воспроизводить подобные баги.
Ад пуст, все бесы здесь.
Re[35]: ConcurrentDictionary vs reference type
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 07.03.22 20:30
Оценка:
Здравствуйте, Codealot, Вы писали:

C>Здравствуйте, Serginio1, Вы писали:


S>> Так ConcurrentDictionary так же делается Lock только на цепоку с одинаковым hash % размер таблицы. Я же тебе код приводил, а ты смеялся.


C>Если делать lock на каждую операцию с коллекцией, то производительность будет пробивать днище. Так что, очевидно, там это не делается.

Ты не читатель. Сказано, же что блокировка не на всю таблицу, а только на hash % размер таблицы.
Посмотри исходники.
S>> Ты же говоришь, что нельзя применять ConcurrentDictionary с ссылочными типами, однако String.Intern прекрасно используют!

C>Нет, я ничего подобного не говорил. Если у ConcurrentDictionary есть гарантии по наличию барьера памяти при добавлении объектов, то проблем с неизменяемыми объектами нет. А вот если бы таких гарантий не было, как заявлял
Автор: samius
Дата: 19.02 01:40
samius, то проблемы несомненно были бы.


Там проблема не в барьере памяти. В любом случае нет проблем с неизменяемыми объектами нет.
Барьеры памяти нужны в основном только для упорядочивания инструкций и не использования регистров. В большинстве это на совести компилятора
и солнце б утром не вставало, когда бы не было меня
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.