|
|
|
что значит, что атомики более finer-grained чем локи?
|
|||
|---|---|---|---|
|
#18+
Поясните пожалуйста эту фразу. автор Atomic variables are finer-grained and lighter-weight than locks, and are critical for implementing high-performance concurrent code on multiprocessor systems. Atomic variables limit the scope of contention to a single variable; this is as fine-grained as you can get (assuming your algorithm can even be implemented using such fine granularity). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.03.2017, 00:55 |
|
||
|
что значит, что атомики более finer-grained чем локи?
|
|||
|---|---|---|---|
|
#18+
IMHO По определению Достаточно перевести одну фразу (вариант электронного переводчика, с небольшими исправлениями): "Atomic variables limit the scope of contention to a single variable; this is as fine-grained as you can get" "Атомарные переменные ограничивают масштабы конфликтов одной переменной; это настолько мелкозернисто, насколько возможно" p.s. плохо знаю английский, но вроде "as you can get" в данном контексте, по смыслу, синоним "as possible" Конечно, можно возразить, что любая переменная состоит из байтов, а байты из битов. Но к сожалению, AFAIK процессора который умел бы блокировать отдельные биты еще не выпустили и в java для работы с ними нет никакой возможности ))) Т.ч. "atomic variables is as fine-grained as you can get" ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.03.2017, 02:57 |
|
||
|
что значит, что атомики более finer-grained чем локи?
|
|||
|---|---|---|---|
|
#18+
Написал хохму про биты, а сейчас подумал, что "в каждой шутке, есть доля не шутки" ( C ). На самом деле, уровень гранулярности на уровне биты, байты, переменные - процессор Intel поддерживать НЕ умеет (процессор и слова "переменные" не знает, но в любом случае гранулярность при доступе что биты, что байты для него одинаково НЕ достижима). Что приводит к определенным проблемам при написании кода при желанием получить "as fine grained as possible" через Atomic'и, которые решаются через одно место (хотя в последней Java специальные конструкции/анотации добавили). Поскольку автор топика уже давно читает про многопотоковость и атомики, думаю, что какой минимальный объект "as fine grained as possible" в Intel процессоре, он уже знать должен. По крайне мере, думаю, что в чужом коде "решение через одно место" он видеть уже точно должен был. В общем, хороший теоретический вопрос на тему автора. Что же на самом деле является "as fine grained as possible" ? Это явно ни "sigle bit", ни "single byte" и соответственно не "single variable", а что-то другое (более крупное). AFAIK ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.03.2017, 03:28 |
|
||
|
что значит, что атомики более finer-grained чем локи?
|
|||
|---|---|---|---|
|
#18+
Возможно с Atomic'ами ошибаюсь. Но с volatile переменными приходится точно идти на ухищрения, что бы они не слипались. Т.к. они слишком мелкозернисты, а процессоры (Intel) такое не поддерживают. / наверное "слипаются" это правильный русский глагол, для описания процесса перехода мелко зернистого объекта в более крупно зернистый ))) / Вроде аналогично и Atomic'и. Хотя не уверен. Но вроде народ так же кучу левого кода пишет. Но это меня всегда удивляло, т.к. атомик отдельный объект, который отдельно выделяется на куче, у меня как-то всегда было изумление, неужели они могут быть настолько малы, что тоже могут слипаться. AFAIK ))) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.03.2017, 03:45 |
|
||
|
что значит, что атомики более finer-grained чем локи?
|
|||
|---|---|---|---|
|
#18+
Сформулирую свой вопрос (Дарю тем, кто проводит собеседования! Я добрый) По определению слова "гранулярность", можно считать что самая мелькозернистая вещь в современных процессорах - это бит. Дальше, я бы расположил так: бит байт (8 бит) машинное слово (для современных процессоров Intel 64 разряда) и так далее Если же говорить про "limit the scope of contention" то гранулярность ни бит, ни байт НЕ достижима (на современных процессорах Intel). При этом, "single variable" так же не достижима. Просто по определению и доказательству от противного. Т.к. можно сделать: volatile char my_variable1; volatile char my_variable2; Т.е. создать две переменные размером в байт. И, к сожалению, т.к. мы знаем, что гранулярность на уровне байта не достижима, то и они тоже не будут в своей работе настолько мелкозернисты, насколько мы бы хотели. Вопрос автору топика: что же является минимально достижимой гранулярностью при доступе из нескольких потоков? Я давно уже предупреждал автора топика, что "от многих знаний, много печалей. Поэтому тот, кто приумножает знания, приумножает скорбь" ))) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.03.2017, 04:15 |
|
||
|
что значит, что атомики более finer-grained чем локи?
|
|||
|---|---|---|---|
|
#18+
В общем, прихожу к тому, что приведенная questionar цитата как минимум не корректна (использование слова/термина "переменная" при описание конкурентного доступа не к месту), а по факту полностью ложна. Более того, я уверен, что (если абстрактный Atomic заменить на AtomicLong, JDK 1.6, современные процессоры Intel) не все что мелкое, то достаточно мелкозернисто. И не все то, что выглядит мелкозернисто, на самом деле таким является. Более крупное, вполне может быть мелкозернистее, чем мелкое (по причине слипания) В общем, это знают даже дети! Когда в песочнице играют в куличики. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.03.2017, 06:25 |
|
||
|
что значит, что атомики более finer-grained чем локи?
|
|||
|---|---|---|---|
|
#18+
x86 прекрасно обеспечивает и гранулярность до байта и атомарность (префикс lock и специальные команды процессора). И нас совершенно не колышет, какие именно циклы обмена на шине запускает при этом аппаратура системы в целом и процессора в частности. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.03.2017, 08:56 |
|
||
|
что значит, что атомики более finer-grained чем локи?
|
|||
|---|---|---|---|
|
#18+
IMHO & AFAIK Хоть кто-то решил мне возразить. А то флудить сам с собой совершенно не интересно ))). Ну и повторюсь, я подхожу чисто с практической точки зрения. Т.к. что бы подходить с теоретической, хорошо бы однозначное определения на русском языке слов вида "гранулярность" и "мелкозернистость" для программирования. более крупное, вполне может быть мелкозернистее, чем мелкое (из за слипаемости) (будет настрой, напишу доказательство и определение терминов на примере песочницы и игры в куличики) Что в свою очередь, на JDK 1.6, Intel может приводить к "ошибке слипаемости" (ошибка==проблемы вызываемые в прикладном коде эффектом самопроизвольного слипания) Что очень хорошо известно, под английским термином False sharing. При котором маленькие объекты (если я правильно понимаю, AtomicLong JDK 1.6 == 16 байт, НЕ проверял), с точки зрения гранулярности и мелкозернистости, могут работать ХУЖЕ, чем более крупные объекты (строка кэша 64 байт для современного Intel). Статьи на хабре конечно больше говорят про кэш. Но по памяти, я буду сильно удивлен, если обмен c DDR (а тем более RDRAM) памятью идет на уровне отдельных слов/байт. Даже в начале 1990-ху РУшки в 16 Кбайт имели блочную организацию. Ну это вообще уже глубокие аппаратные дебри, в которых я не разбираюсь и залезать в которые не хочется. Т,к. на практике, попытка админам (в успевающей компании, сотни серверов на Amazon, куплины три серверные по всему миру) задать вопрос, "у нас же NUMA сервер, не может это являться проблемой?" выявила полное изумление на лицах ))) Рассматривая приведенный мною пример: volatile char my_var1; volatile char my_var2; .... volatile char my_var64; Мы, можем наивно думать, что у нас есть "fine grained" доступ или управление отдельными переменными. На самом деле, это не так! В худшем случае, все эти переменные при конкурентом доступе будут вести себя как ОДНА! Практически, если это некоторые флаги/блокировки, то получается, что вместо 64 флагов/блокировок (якобы fine grained) мы могли бы использовать одну (пусть и не настолько fine grained) и получить такую же или, скорее всего, даже значительно лучшую производительность. Слова "значительно лучшую" могут даже значит в десятки и сотни раз. Т.е., говоря грубо, если у нас есть ПРОБЛЕМА, и МУСОР из раковины не успевает уйти в канализационную трубу, то решение проблемы методом "измельчения мусора" и усиленным его проталкиванием в раковину может быть "не так очевидно" ( C ) Дочь офицера Даже получив временный и значительный выйгрышь, мы можем получить (а может и пронесет) п...ц в дальнейшем, если окажется, что хорошо размельченной мусор, способен слипаться в трубе (или в магистральной трубе). Можно привести пример из жизни, которые все могут повторить у себя дома: Остатки цементного раствора, ну или даже шпаклевки (более лайт вариант ))) ), при ремонте совершенно замечательно сливаются в унитаз. Т.к. представляют из себя совершенно нормальное и мелькозернистое вещество. Но, если они успеют слипнутся в канализационной трубе при выходе из дома..... хотя по сравнению с плавающими в реальности по канализации бревнами или какой нибудь аварией магистрального туннельного коллектора это конечно мелочь )))) В общем не важно где произошла слипания или коагуляция потока (flow) данных и образовался осадок. Для современных серверов можно сходу назвать несколько места при доступе к RAM, где из-за коагуляции может образоваться мелководные дельты мешающие нормальному data или process flow: 1) кэш (например false sharing) 2) коллизии на шине вызванные поддержкой когеренции (полно статей, но собственно с java примеров не видел) 3) NUMA Ну и при проектирование реальных систем, хорошо бы не забывать: 1) Обмен данными между потоками 2) Обмен данными между процессами 3) Обмен данными между нодами / серверами 4) Ну и банальный ввод-вывод на диск и так далее Все это, хорошо известные примеры, когда крупное, проходить сквозь "дырочку" значительно быстрее, чем мелкое. Если на False Sharing в последней java ( JDK 1.8 ) вроде под нажимом сообщества внимание обратили, то с Numa хоть работы и проводятся, но на уровне Java Heap вроде результаты совсем не утешительные (алгоритмы реализованные в JDK 1.8 по тестам и мнению самих авторов, дают выигрыш значительно меньший, чем ожидалось теоретически и не стоят даже мускульного напряжения при вводе -numa в командной строке java ))) ). Т.е. с Numa нужно бороться (если хочется high performance) на уровне архитектуры и настройки ОС на сервере. На практике, сам наблюдал картину, когда из-за изменения паттерна нагрузки на потоки (перевод прикладной системы с "обычного" http на NIO /apache NIO/) при всем прочем равном (полезный бизнес код не трогался), физическая нагрузка на CPU возросла в 3-4 раза ! (а с учетом, что пробег электронов при решении бизнес кода не поменялся, это вообще феерический п...ц) при том, что количество потоков сократилось в десятки раз (кол-во одновременных соединений 150-300) При таком степени п...ц на высоком уровне (железо, ОС, архитектура, JVM), заниматься оптимизацией и попыткой "выжать" 5-10 процентов благодаря якобы (!!!!) fined grained методам синхронизации - на мой взгляд бессмысленно. Atomic'и написаны и хорошо выполняют конкретную задачу. Вот по этому назначению их и нужно использовать. IMHO На практике, видел (и сам пытался делать) код порожденный попыткой поднять производительность за свой синхронизации на Atomic'ах. По факту: 1) Код на атомиках становится п....ц насколько не понятным. Т.к. вроде логичное и понятное правило барьеров при synchronized, при тех же атомиках в прикладном коде становистя п...ц как не понятно и п...ц как непонятно работающее При этом ошибки вида: случайно раз в час, один раз на сотню миллионов интераций, переменная приходит не успев проинициализироваться - даже в причинах фиг разберешься. Твоя ли это ошибка, плохо-документированная фича Java, твое неправильное прочтение документации или банальная ошибка в коде JVM 2) Поскольку, на практике, в результате таких действий один synchronized меняется обычно на несколько Atomic'ах - даже при приросте в тесте, реальная осмысленность становится крайне сомнительной. Т.к. Just-in-time компилятор выполняет анализ кода и может реализовывать РАЗНОЕ поведение для Synchronized. В том числе и такие алгоритмы, которые по определению быстрее того, что могут дать Atomic'и, блокировки и потоки ! Т.ч. по практике AFAIK высока вероятность получения "самопального" кода, с сложностью последующего сопровождения/модификации, падению надежности, сомнительном выйгрыше в производительности и, самое главное, с сомнительной портабильностью. Т.к. может оказаться, что сложный код на Atomic'ах vs простой на синхронайзах на одних версиях JDK и железе окажется быстрее на 10-20%, а на других версиях и железе медленнее в десятки и сотни раз. Просто потому, что JIT правильно или не правильно синхронайз оптимизировала. IMHO, AFAIK, по практике. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.03.2017, 16:03 |
|
||
|
что значит, что атомики более finer-grained чем локи?
|
|||
|---|---|---|---|
|
#18+
Leonid KudryavtsevПри котором маленькие объекты (если я правильно понимаю, AtomicLong JDK 1.6 == 16 байт, НЕ проверял), с точки зрения гранулярности и мелкозернистости, могут работать ХУЖЕ, чем более крупные объекты (строка кэша 64 байт для современного Intel)Насколько я понял из доклада Куксенко (Шипилёва?.. Склероз ...), классы-обёртки (атомики - в том числе) хранят примитивы (для Oracle JVM) в заголовке объекта. Сам заголовок - 12 байт. Будет ли он выровнен на строку (на 16 байт) - вопрос.Но по памяти, я буду сильно удивлен, если обмен c DDR (а тем более RDRAM) памятью идет на уровне отдельных слов/байт.Я не зря упоминал циклы процессора и прочей аппаратуры. Конкретно x86 (x86-64 - в том числе) архитектура обладает разными приятными свойствами. Например умеет читать байт (8 бит) слово (16 бит), двойное и четверное слово уже давным-давно и даже если слова не выровнены на естественные границы. Физически память, конечно, 64-битная, но байтовые чтения из неё никому не заказаны. P.S. Не могу аргументировать практическим опытом, но, если требуется высокая скорость, то правило "большого пальца" очень простое: только 64-разрядная JVM и, желательно, JVM8. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.03.2017, 11:00 |
|
||
|
что значит, что атомики более finer-grained чем локи?
|
|||
|---|---|---|---|
|
#18+
questioner, Что бы не умничать и не вдаваться в особенности железа, поясню так: Процессор для для выполнения операции с, например int значением выполняет машинную команду (какую не важно, да я уже и не помню, скажем, GET). В то время, когда он выбирает эти четыре байта из памяти командой GET, весь остальной код, независимо от того, сколько еще на компе есть процессоров НЕ можт обратится к этим же 4-м байтам ни для их чтения, ни для из модификации. Таким образом, получаем естественный lock. Другое дело double или float. Чтобы с ним что-то сделать, процессор выполняет несколько своих машинных команд. Например, первая команда выберет 4 байта. А другой процессор в это же время может записать данные в следующие 4 байта double значения. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.03.2017, 10:52 |
|
||
|
что значит, что атомики более finer-grained чем локи?
|
|||
|---|---|---|---|
|
#18+
С появлением у x86 встроенного кэша (i486, ~1989 г.), заполнение кэш-строки (16 байт) делается специальным циклом. Таким образом, аппаратно, x86-системы гарантируют атомарные обращения к (выровненным) 16-байтовым строкам. До появления x86-64 атомарное обращение к восьми байтам мог делать только сопроцессор ( гарантировано встроен начиная с Pentium, ~1993 г.). Другой вопрос, что работа с FPU может и замедлить код, т.к. требует разных приседаний, но, как я понимаю, появление SIMD (MMX/3Dnow! и далее) сильно улучшило ситуацию. 64-разрядные JVM (и только они) получают атомарные обращения к long "забесплатно", а вот 32-разрядные - зависят, как я понимаю, от наличия SSE, который на x86 есть везде и уже давно. В целом, я бы сказал так: оптимальный размер переменных для конкурентных алгоритмов - int, даже если "достаточно одного бита". Если вам хочется сэкономить памяти, вы, скорее всего, что-то не то делаете. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.03.2017, 11:40 |
|
||
|
|

start [/forum/topic.php?fid=59&gotonew=1&tid=2123057]: |
0ms |
get settings: |
10ms |
get forum list: |
15ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
56ms |
get topic data: |
10ms |
get first new msg: |
6ms |
get forum data: |
3ms |
get page messages: |
60ms |
get tp. blocked users: |
2ms |
| others: | 231ms |
| total: | 399ms |

| 0 / 0 |
