Re[27]: Потокобезопасность инициализации Comparer<T>.Default
От: VladD2 Российская Империя www.nemerle.org
Дата: 30.01.09 19:21
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Из-за этого можно упасть только на взлете.

WH>После того как сервер прогрелся из-за этого уже не упасть.

Вот хоть бы раз хоть одно приложение упало бы на взлете из-за проблем с потоками и коллекциями...
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[28]: Потокобезопасность инициализации Comparer<T>.Default
От: nikov США http://www.linkedin.com/in/nikov
Дата: 30.01.09 20:26
Оценка: +1
Здравствуйте, VladD2, Вы писали:

WH>>Из-за этого можно упасть только на взлете.

WH>>После того как сервер прогрелся из-за этого уже не упасть.

VD>Вот хоть бы раз хоть одно приложение упало бы на взлете из-за проблем с потоками и коллекциями...


Ну говорю же: в реальной жизни такого не бывает, потому что текущая реализация MS работает надежнее. Об этом даже Рихтер писал.
Re: Потокобезопасность инициализации Comparer<T>.Default
От: vdimas Россия  
Дата: 02.02.09 10:19
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>За тем что второй поток может увидеть указатель на компатор до того как тело компатора приедит к нему.

WH>Для того чтобы гарантировать что второй поток полностью увидит тело компатора нужен барьер памяти.

Перемудрил.
Это если бы два потока до этого обращались к области памяти _создаваемого_ объекта, то был бы прав, а так это практически невозможно.
Re[6]: Потокобезопасность инициализации Comparer<T>.Default
От: mrTwister Россия  
Дата: 02.02.09 10:21
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Слушай кончай антазировать. Нет там никаких проблем. Копирование ссылки — атомарная операция. Объект сначала формируется, а потом ссылка на него помещается в переменную. Неинициализированного объекта никто не увидит. Самое страшное, что случится — это могут создаться несколько копий компораторов, но так как они все равно будут идентичны, то по фигу кто какую копию будет использовать. Итого проблем тут быть не может.


Несмотря на то, что оно работает, никто не дает гарантий, что оно и дальше будет работать. Просто в текущей реализации все операции записи в .NET volatile (по крайней мере на x86). А по теории надо надо явно обозначать это, где надо.
лэт ми спик фром май харт
Re[3]: Потокобезопасность инициализации Comparer<T>.Default
От: vdimas Россия  
Дата: 02.02.09 10:24
Оценка:
Здравствуйте, WolfHound, Вы писали:

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


VD>>Я не вижу тут проблем:

WH>хъ
VD>>Comparer<T>.defaultComparer присваивается в самом конце когда компаратор уже сформирован.
WH>Следи за рукам: Есть 2 разных куска памяти.
WH>Первый содержит сам компатор. Второй содержит ссылку на компатор.
WH>Если второй поток сначала получит второй кусок памяти и не получит первый (на некоторых архитектурах такое возможно) получим чтение не пойми чего и как следствие не пойми какие последствия.

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

WH>Если вставить барьер памяти то второй поток гарантировано увидит первый кусок памяти раньше чем второй.


И так гарантированно, ибо только через разыменование.
Re[8]: Потокобезопасность инициализации Comparer<T>.Default
От: mrTwister Россия  
Дата: 02.02.09 10:24
Оценка:
Здравствуйте, Константин Л., Вы писали:

КЛ>1. Выделяется память

КЛ>2. На ней зовется ctor
КЛ>3. Ссылка на память присваивается переменной

КЛ>Вы патаетесь сказать, что порядок может быть 1,3,2? Какой в этом смысл?


Нет, ссылка присваивается переменной, а тот участок памяти, куда указывает ссылка, на другом процессоре ещё старый (процессорный кэш не успел обновиться).
лэт ми спик фром май харт
Re[9]: Потокобезопасность инициализации Comparer<T>.Default
От: Константин Л. Франция  
Дата: 02.02.09 10:35
Оценка:
Здравствуйте, mrTwister, Вы писали:

T>Здравствуйте, Константин Л., Вы писали:


КЛ>>1. Выделяется память

КЛ>>2. На ней зовется ctor
КЛ>>3. Ссылка на память присваивается переменной

КЛ>>Вы патаетесь сказать, что порядок может быть 1,3,2? Какой в этом смысл?


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


Это все лирика и к FW никакого отношения не имеет. Уже 10 раз прошу показать ссылку на стандарт, где написано, что такая ситуация возможна.
Re[28]: Потокобезопасность инициализации Comparer<T>.Default
От: mrTwister Россия  
Дата: 02.02.09 10:39
Оценка:
Здравствуйте, Константин Л., Вы писали:

КЛ>Всё новые и новые знания ты нам открываешь. Источник бы...


Ну, например, Рихтер об этом пишет.
лэт ми спик фром май харт
Re[10]: Потокобезопасность инициализации Comparer<T>.Default
От: mrTwister Россия  
Дата: 02.02.09 10:55
Оценка:
Здравствуйте, Константин Л., Вы писали:

КЛ>Это все лирика и к FW никакого отношения не имеет. Уже 10 раз прошу показать ссылку на стандарт, где написано, что такая ситуация возможна.


В стандарте ни слова не сказано, что FW обязан сбрасывать кэш на всех процессорах после каждой операции записи на любом из процессоров. Следовательно, не обязан. Именно для этого введено слово volatile — оно помечает переменные, обращение к которым автоматически сбрасывает кэши. Шутка в том, что в текущей реализации FW все переменные работают, как volatile.
лэт ми спик фром май харт
Re[11]: Потокобезопасность инициализации Comparer<T>.Default
От: Константин Л. Франция  
Дата: 02.02.09 11:15
Оценка:
Здравствуйте, mrTwister, Вы писали:

T>Здравствуйте, Константин Л., Вы писали:


КЛ>>Это все лирика и к FW никакого отношения не имеет. Уже 10 раз прошу показать ссылку на стандарт, где написано, что такая ситуация возможна.


T>В стандарте ни слова не сказано, что FW обязан сбрасывать кэш на всех процессорах после каждой операции записи на любом из процессоров. Следовательно, не обязан. Именно для этого введено слово volatile — оно помечает переменные, обращение к которым автоматически сбрасывает кэши. Шутка в том, что в текущей реализации FW все переменные работают, как volatile.


Не надо только путать сбрасывание кешей, volatile и такую ситуацию, которую мы рассматриваем. Кстати, если Рихтер пишет, то ссылку плиз.
Re[18]: Потокобезопасность инициализации Comparer<T>.Default
От: nikov США http://www.linkedin.com/in/nikov
Дата: 02.02.09 13:07
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>А что он читать то будет? Откуда у него кэш взялся? Он же к этой области памяти еще не обращался. Если же у него есть кэш, то он и нули может не увидеть.


Да мало ли какой код мог в этом потоке работать... Может быть, эта память читалась с помощью unsafe кода (например, в приложении есть memory viewer).
Re[18]: Потокобезопасность инициализации Comparer<T>.Default
От: nikov США http://www.linkedin.com/in/nikov
Дата: 02.02.09 16:27
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>А что он читать то будет? Откуда у него кэш взялся? Он же к этой области памяти еще не обращался. Если же у него есть кэш, то он и нули может не увидеть.


Еще, например, GC-поток мог работать на этом же процессоре.
Re[19]: Потокобезопасность инициализации Comparer<T>.Default
От: Sinix  
Дата: 04.02.09 08:05
Оценка:
9 страниц переспрашивания... Не надоело?

Когда читал у Рихтера — отложилось в памяти так:

Многопоточное обращение к инициализируемой переменной может привести к получению ссылки на забитую нулями область памяти из-за того что ссылка уже проинициализирована и сброшена из кэша в память, а _сам_ объект ещё нет.

Вероятность такого события крайне мала и определяется архитектурой процессора/неоднородностью памяти/моделью синхронизации кэша и памяти/порядком выполнения команд и т.п. Классический пример — intel itanium, который допускает частичяное переупорядочивание команд записи. Чтобы такой ситуации не возникало следует перед обращением к переменной сфлушить кеш в память — тот самый memory barrier что гарантирует последовательность операций с памятью (т.е. что запись произойдёт _до_ чтения). В дотнете это сделано из коробки, но поскольку такое поведение не гарантируется стандартом (в bcl team блоге по
этому поводу сокрушались ещё в 2к4-м), будьте любезны озаботиться синхронизацией явно. В чём проблемы???

P.S. если бы сделали static readonly defaultComparer = new Comparer<T>(); + cctor чтобы получить beforefieldinit на поле — разговаривать было бы не о чем — JIT сам добавил бы лок.

Как дети малые — почему, почему... матчасть учить надо...
Re[20]: Потокобезопасность инициализации Comparer<T>.Default
От: Константин Л. Франция  
Дата: 04.02.09 08:57
Оценка:
Здравствуйте, Sinix, Вы писали:

S>9 страниц переспрашивания... Не надоело?


нет, тк без пруфлинка это всего-лишь слова

S>Когда читал у Рихтера — отложилось в памяти так:


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


S>Вероятность такого события крайне мала и определяется архитектурой процессора/неоднородностью памяти/моделью синхронизации кэша и памяти/порядком выполнения команд и т.п. Классический пример — intel itanium, который допускает частичяное переупорядочивание команд записи. Чтобы такой ситуации не возникало следует перед обращением к переменной сфлушить кеш в память — тот самый memory barrier что гарантирует последовательность операций с памятью (т.е. что запись произойдёт _до_ чтения). В дотнете это сделано из коробки, но поскольку такое поведение не гарантируется стандартом (в bcl team блоге по

S>этому поводу сокрушались ещё в 2к4-м), будьте любезны озаботиться синхронизацией явно. В чём проблемы???

Проблемы в том, что это все в общем относится к самой платформе, но не к FW. Мне все-лишь нужно место в стандарте, где описывается не такое поведение на какой-то платформе, а такое поведение FW на какой-то платформе. У нас тут не с++.

S>P.S. если бы сделали static readonly defaultComparer = new Comparer<T>(); + cctor чтобы получить beforefieldinit на поле — разговаривать было бы не о чем — JIT сам добавил бы лок.


S>Как дети малые — почему, почему... матчасть учить надо...


предлагаю заняться тем же
Re[21]: Потокобезопасность инициализации Comparer<T>.Default
От: Sinix  
Дата: 04.02.09 09:10
Оценка:
Здравствуйте, Константин Л.

S>>9 страниц переспрашивания... Не надоело?

КЛ>нет, тк без пруфлинка это всего-лишь слова

Ecma 335 вам цитатили вроде. Рихтера щас не полистаю — дома он. Но так оно, так — поверьте Погуглите по сочетанию "clr itanium memory barrier volatile". Скорее всего найдётся.

КЛ>Проблемы в том, что это все в общем относится к самой платформе, но не к FW. Мне все-лишь нужно место в стандарте, где описывается не такое поведение на какой-то платформе, а такое поведение FW на какой-то платформе. У нас тут не с++.


Оно относится к некоей гипотетической реализации рантайма на некоей гипотетической платформе. Проблема только в излишней мягкости стандарта. В реализации clr от МС (начиная с 2.0 насколько помню. А может и 1.1.сп1... но вряд ли.) это решается из коробки volatile-по-умолчанию полями.

S>>Как дети малые — почему, почему... матчасть учить надо...

КЛ>предлагаю заняться тем же

Дык всё время...
Re[22]: Потокобезопасность инициализации Comparer<T>.Default
От: Константин Л. Франция  
Дата: 04.02.09 09:27
Оценка:
Здравствуйте, Sinix, Вы писали:

S>Здравствуйте, Константин Л.


S>>>9 страниц переспрашивания... Не надоело?

КЛ>>нет, тк без пруфлинка это всего-лишь слова

S>Ecma 335 вам цитатили вроде. Рихтера щас не полистаю — дома он. Но так оно, так — поверьте Погуглите по сочетанию "clr itanium memory barrier volatile". Скорее всего найдётся.


То, что цитировали к делу не имеет никакого отношения. Так, общие слова, не более. Че-та не гуглится

КЛ>>Проблемы в том, что это все в общем относится к самой платформе, но не к FW. Мне все-лишь нужно место в стандарте, где описывается не такое поведение на какой-то платформе, а такое поведение FW на какой-то платформе. У нас тут не с++.


S>Оно относится к некоей гипотетической реализации рантайма на некоей гипотетической платформе. Проблема только в излишней мягкости стандарта. В реализации clr от МС (начиная с 2.0 насколько помню. А может и 1.1.сп1... но вряд ли.) это решается из коробки volatile-по-умолчанию полями.


[]
Re[28]: Потокобезопасность инициализации Comparer<T>.Default
От: Sinclair Россия https://github.com/evilguest/
Дата: 05.02.09 08:09
Оценка:
Здравствуйте, Константин Л., Вы писали:
КЛ>Я не про то что должны, а про то что это было бы логично и эффективно
Это было бы нелогично и неэффективно. На всякий случай напомню, что ссылка может быть в том числе и на массив, вполне произвольного размера. А кэш — не резиновый. У тебя запросто может быть цикл, (код которого естественно сам лежит в кэше), который бежит по массиву стрингов (который не обязан лежать рядом в с кодом в памяти) и с каждой строкой что-то делать, сканируя все ее символы.
С точки зрения кэша вполне нормально держать каждый из этих фрагментов в отдельной линейке — кэша вполне хватит на то, чтобы обеспечить 90-99% cache hit ratio в таких условиях. Несмотря на то, что суммарный объем строк сушественно превышает ёмкость кэша.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[29]: Потокобезопасность инициализации Comparer<T>.Default
От: Константин Л. Франция  
Дата: 05.02.09 10:20
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Здравствуйте, Константин Л., Вы писали:

КЛ>>Я не про то что должны, а про то что это было бы логично и эффективно
S>Это было бы нелогично и неэффективно. На всякий случай напомню, что ссылка может быть в том числе и на массив, вполне произвольного размера. А кэш — не резиновый. У тебя запросто может быть цикл, (код которого естественно сам лежит в кэше), который бежит по массиву стрингов (который не обязан лежать рядом в с кодом в памяти) и с каждой строкой что-то делать, сканируя все ее символы.
S>С точки зрения кэша вполне нормально держать каждый из этих фрагментов в отдельной линейке — кэша вполне хватит на то, чтобы обеспечить 90-99% cache hit ratio в таких условиях. Несмотря на то, что суммарный объем строк сушественно превышает ёмкость кэша.

а теперь давай представим что это не массив.
Re[30]: Потокобезопасность инициализации Comparer<T>.Default
От: Sinclair Россия https://github.com/evilguest/
Дата: 05.02.09 10:54
Оценка:
Здравствуйте, Константин Л., Вы писали:
КЛ>а теперь давай представим что это не массив.
И? Положение объекта в кэше определяется его расположением в памяти. Расположение в памяти определяется (в дотнете) порядком создания объектов. Память под ссылку в данном случае выделяется при инициализации класса, т.е. в момент загрузки сборки. Память под объект выделяется в момент первого обращения — за это время указатель на вершину хипа убежал черти куда. Поэтому шансов на то, что ссылка будет прямо рядом с данными, на которые она показывает, очень мало. Это в данном контексте. То бишь, пытаться сделать наоборот было бы нелогично и неэффективно.

То, о чем ты говоришь, может иметь место только в случаях специальных структур данных. Например, связных списков или деревьев — там, в случае быстрых массовых модификаций, есть шансы более-менее плотно занять память.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[6]: Потокобезопасность инициализации Comparer<T>.Default
От: remark Россия http://www.1024cores.net/
Дата: 18.02.09 20:56
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Слушай кончай антазировать. Нет там никаких проблем. Копирование ссылки — атомарная операция. Объект сначала формируется, а потом ссылка на него помещается в переменную. Неинициализированного объекта никто не увидит.


Атомарность тут совсем ни при чём. Тебе говорят про относительное упорядочивание обращений к памяти.
Если ты опускаешься ниже "каждый доступ защищён мьютексом", то действительно должен перестать думать последовательно, sequential consistency сейчас уже никто в здравом уме не предоставляет. Это значит, что ты должен перестать думать "это происходит до этого, значит то происходит перед вот этим", по крайней мере основываясь на программном порядке — программный порядок НЕ соблюдается в многопоточном окружении!
Что такое модель памяти? И с чем её едят?
Автор: remark
Дата: 20.11.08



1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.