Re[16]: Языки для распараллеленных вычислений
От: chaotic-kotik  
Дата: 01.10.16 13:12
Оценка:
Здравствуйте, WolfHound, Вы писали:

CK>>Good luck with that.

WH>https://github.com/google/sanitizers/issues/621
WH>Зубы на полку.

Ладно, уел. (хотя я не припомню data-race-ов на глобальных переменных (не используем) или стековых переменных в своей практике)

CK>>Чойта?

WH>Жизнь такая.

Я бы сказал что это чрезмерное обобщение. За ним обязательно должна следовать ссылка на что-нибудь, подтверждающее твои слова. Если я напишу "системы типов не уменьшают число багов" просто так, заклюете же.

CK>>Все приложения требуют тестирования и любой код может потенциально содержать баги.

WH>Только стоимость отладки разных типов багов отличается в разы если не на порядки.

Еще одно спорное утверждение. Пересобрал с tsan-ом, воспроизвел и все. Можно еще под helgrind-ом запустить.

CK>>Если код не трогает одну и ту же память одновременно из разных потоков, это еще не означает, что он потокобезопасен.

WH>Рассказывай дальше. Что там такое может произойти?

Race condition же, или ты считаешь что data race это единственная разновидность race condition? Что нибудь в духе:

if (queue.empty()) { // lock-free queue
    connection.close();  // здесь queue.empty() уже равно false
}


или такое тоже можно отловить?

CK>>Есть класс дыр в безопасности, т.н. double fetch vulnerabilities вызванных именно race-ами, но ты едва ли сможешь избавиться от них с помощью системы типов.

WH>Есть несколько разных систем типов которые убивают гонки с 100%ной гарантией.

Например?

CK>>Я же не говорю что это не нужно, только то, что это не очень полезно, так как thread safety и liveliness не гарантирует.

WH>Ты не крути. Ты расскажи, что может произойти если гонок нет от слова совсем.

Starvation/priority inversion, thundering herd, deadlock, livelock, lock contention (крайние проявления по крайней мере).
Re[14]: Языки для распараллеленных вычислений
От: Evgeny.Panasyuk Россия  
Дата: 01.10.16 17:29
Оценка:
Здравствуйте, WolfHound, Вы писали:

EP>>Необязательно. Например верификатор может ограничить всё глобальное взаимодействие до одного объекта очереди сообщений.

WH>Слишком сильное ограничение.

Во-первых, это лишь простейший пример для демонстрации идеи, причём рабочий. В реальности верификатор может разрешать более сложный сценарии.
Во-вторых, в штуках типа Erlang на подобных очередях сообщений всё и построено

EP>>Да и аннотации уже есть во многих языках, если же нет — то можно для этой цели использовать типы.

WH>Так это и получается язык с компилятором, но через зад автогеном.

Верификатор это не компилятор.
Re[12]: Языки для распараллеленных вычислений
От: Evgeny.Panasyuk Россия  
Дата: 01.10.16 17:44
Оценка:
Здравствуйте, VladD2, Вы писали:

EP>>Не обязательно язык, и даже необязательно компилятор. Достаточно внешнего верификатора.

VD>Это равносиельно языку.

Нет. По-твоему какой-нибудь Lint'ер, Resharper, предупреждатор превращает язык в другой?
Но это уже вопрос терминологии, и не особо интересно.

VD>Ну, и не факт что достаточно.


Достаточно для чего? Например в Erlang всё на очердях сообщений и построено.

VD>Для это "верификации" нужна модель.


Модель чего? Ясное дело что будет некоторая спецификация — верификатор лишь будет её форсировать.

VD>Плюс нужна поддержка в рантайме.


Это может быть обычной библиотекой.

VD>Короче, если бы все был так просто, то проблему эту уже давно решили.


А я не говорю что это супер просто. Это вполне возможно, и отдельный язык для этого не нужен.
Проблемы с очередями сообщений и подобным — например в производительности. На локах, а тем более atomics, нужно лисапедить когда недостаточно отработанных решений типа очередней сообщений, акторов, CSP и прочего.

VD>Но что-то решения не видно не смотря на монструозные коллективы работающие над этим в Майкрософт, Гугле и Оракле.


Решения чего? Кривых рук которые сломя голову хватаются за низкоуровневые примитивы синхронизации в тех случаях когда достаточно высокоуровневых, и вполне закономерно бегают по граблям?
Re[11]: Языки для распараллеленных вычислений
От: Evgeny.Panasyuk Россия  
Дата: 01.10.16 17:49
Оценка:
Здравствуйте, chaotic-kotik, Вы писали:

CK>Помимо этого есть еще проблема композиции. В многопоточном программировании, если твоя программа состоит из thread-safe элементов (все коллекции и объекты используют мьютексы например), это не значит что программа является корректной и потокобезопасной.


Отчасти эту проблему пытаются решить посредством STM — software transactional memory.
Re[5]: Языки для распараллеленных вычислений
От: Философ Ад http://vk.com/id10256428
Дата: 01.10.16 18:55
Оценка: +1
Здравствуйте, Khimik, Вы писали:

K>Здравствуйте, Evgeny.Panasyuk, Вы писали:


EP>>Запустится несколько потоков и будет произведена параллельная редукция — проблемы нет, так как операция умножения ассоциативна:

EP>>
EP>>template<typename T>
EP>>T factorial(T N)
EP>>{
EP>>    T result = 1;

EP>>    #pragma omp parallel for reduction(*:result)
EP>>    for(T i = 1; i <= N; ++i)
EP>>        result *= i;

EP>>    return result;
EP>>}
EP>>


А во что это в итоге скомпилируется? Оно не получится медленнее чем однопоточный варинант? Не превысят ли накладные расходы на распараллеливание выигрыш от самого распараллеливания?
Всё сказанное выше — личное мнение, если не указано обратное.
Re[6]: Языки для распараллеленных вычислений
От: Evgeny.Panasyuk Россия  
Дата: 01.10.16 21:06
Оценка:
Здравствуйте, Философ, Вы писали:

Ф>А во что это в итоге скомпилируется?


В параллельную редукцию. Например каждому потоку, число M которых соответствует числу вычислительных единиц, дадут задание в собственном под-диапазоне, что возможно за счёт ассоциативности.
Потом эти M результатов свернут в один, в соответствии с операцией. Если M достаточно большое — то эти M значений опять могут разбить на параллельные под-диапазоны.
Конкретные детали зависят от реализации OpenMP. Но думаю вопрос не в этих деталях, так как аналогичная техника реализуется и без расширений языка, посредством ФВП — например Intel TBB, или Microsoft PPL.

Ф>Оно не получится медленнее чем однопоточный варинант? Не превысят ли накладные расходы на распараллеливание выигрыш от самого распараллеливания?


Очевидно зависит от стоимости ассоциативной операции и входного N, так как накладные расходы от них практически не зависят.
Re[15]: Языки для распараллеленных вычислений
От: WolfHound  
Дата: 02.10.16 11:05
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Во-вторых, в штуках типа Erlang на подобных очередях сообщений всё и построено

Разговаривал я с реальными ерлангистами. Рассказывали они как оно работает в реальности, а не в маркетинговых статьях.
Короче очень плохо оно работает.
И что самое смешное рассказывали примерно те же самые жутики что я предсказал, изучив модель эрланга.

WH>>Так это и получается язык с компилятором, но через зад автогеном.

EP>Верификатор это не компилятор.
Добавление аннотаций == изменение языка.
Верификатор == компилятор — генерация кода.
... << RSDN@Home 1.0.0 alpha 5 rev. 0>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[17]: Языки для распараллеленных вычислений
От: WolfHound  
Дата: 02.10.16 11:05
Оценка:
Здравствуйте, chaotic-kotik, Вы писали:

CK>Ладно, уел. (хотя я не припомню data-race-ов на глобальных переменных (не используем) или стековых переменных в своей практике)

Смысл в том что решение не имеет под собой точной математической модели, а значит не может обеспечить гарантий.
И кто знает сколько там ещё false negative по углам прячется.
Ибо false positive находятся довольно легко, а false negative только если программист сам откопал.

CK>Я бы сказал что это чрезмерное обобщение. За ним обязательно должна следовать ссылка на что-нибудь, подтверждающее твои слова.

Насмотрелся я на разные попытки писать многопоточные программы.
Пока есть железная дисциплина и код придерживается некоторой модели исполнения то они чаще работают чем нет. Но шаг в сторону и начинается...

CK>Если я напишу "системы типов не уменьшают число багов" просто так, заклюете же.

Обязательно. Ибо системы типов исключают целые классы ошибок.

CK>Еще одно спорное утверждение. Пересобрал с tsan-ом, воспроизвел и все. Можно еще под helgrind-ом запустить.

Про tsan мы уже выяснили.

CK>Race condition же, или ты считаешь что data race это единственная разновидность race condition?

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

CK>Что нибудь в духе:

CK>
CK>if (queue.empty()) { // lock-free queue
CK>    connection.close();  // здесь queue.empty() уже равно false
CK>}
CK>

CK>или такое тоже можно отловить?
1)Метод empty в очереди сообщений мягко говоря сомнителен.
При нормальном дизайне там должен быть метод isClosed означающий что сообщений больше не будет.
2)Доставка сообщений с гарантией — это отдельный большой вопрос.

WH>>Есть несколько разных систем типов которые убивают гонки с 100%ной гарантией.

CK>Например?
Раз: Re[13]: Языки для распараллеленных вычислений
Автор: WolfHound
Дата: 28.09.16

Два: http://www.ponylang.org/

CK>Starvation/priority inversion, thundering herd, deadlock, livelock, lock contention (крайние проявления по крайней мере).

Ещё раз. Это всё равно что заявлять, что статическая типизация не нужна, ибо позволяет написать вместо линейного алгоритма квадратичный.
... << RSDN@Home 1.0.0 alpha 5 rev. 0>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[16]: Языки для распараллеленных вычислений
От: Evgeny.Panasyuk Россия  
Дата: 02.10.16 12:45
Оценка:
Здравствуйте, WolfHound, Вы писали:

EP>>Во-вторых, в штуках типа Erlang на подобных очередях сообщений всё и построено

WH>Разговаривал я с реальными ерлангистами. Рассказывали они как оно работает в реальности, а не в маркетинговых статьях.
WH>Короче очень плохо оно работает.
WH>И что самое смешное рассказывали примерно те же самые жутики что я предсказал, изучив модель эрланга.

Это всё здорово, и у модели Erlang есть действительно определённые недостатки/проблемы.
Вот только не надо уходить в сторону от исходного обсуждения, а именно от того насколько трудно гарантировать отсутствие одновременного доступа из нескольких потоков к данным которые к этому не готовы — в обсуждаемом примере с верификатором эта задача решается ограничением глобального доступа только к одной потокобезопасной очереди

WH>>>Так это и получается язык с компилятором, но через зад автогеном.

EP>>Верификатор это не компилятор.
WH>Добавление аннотаций == изменение языка.

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

WH>Верификатор == компилятор — генерация кода.


Не обязательно. Например в верификатор может быть заложена куда более простая модель языка нежели чем в компилятор. Например очевидно что верификатор гарантирующий отсутствие одного из ключевых слов в коде — намного проще того что есть в "компилятор — генератор"
Re[17]: Языки для распараллеленных вычислений
От: WolfHound  
Дата: 02.10.16 13:01
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Вот только не надо уходить в сторону от исходного обсуждения, а именно от того насколько трудно гарантировать отсутствие одновременного доступа из нескольких потоков к данным которые к этому не готовы — в обсуждаемом примере с верификатором эта задача решается ограничением глобального доступа только к одной потокобезопасной очереди

Ты себя послушай... "глобального доступа только к одной потокобезопасной очереди" == ограничение возможностей языка == другой язык.
Одна из основных задач компилятора — определение того принадлежит ли текст программы к языку.
... << RSDN@Home 1.0.0 alpha 5 rev. 0>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[18]: Языки для распараллеленных вычислений
От: Evgeny.Panasyuk Россия  
Дата: 02.10.16 13:12
Оценка:
Здравствуйте, WolfHound, Вы писали:

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


По-твоему какой-нибудь Lint'ер, Resharper, предупреждатор превращает язык в другой?
ОК, возможно, но это уже вопрос терминологии, и не особо интересно
Re[18]: Языки для распараллеленных вычислений
От: chaotic-kotik  
Дата: 03.10.16 17:21
Оценка:
Здравствуйте, WolfHound, Вы писали:

CK>>Если я напишу "системы типов не уменьшают число багов" просто так, заклюете же.

WH>Обязательно. Ибо системы типов исключают целые классы ошибок.

Вопрос не об этом был.

CK>>Еще одно спорное утверждение. Пересобрал с tsan-ом, воспроизвел и все. Можно еще под helgrind-ом запустить.

WH>Про tsan мы уже выяснили.

Ничего мы про него еще не выяснили. Если крайне полезный инструмент с небольшой вероятностью может дать false negative, то это не значит что он бесполезен. Ну и что что нет "гарантии". Гарантии никогда нет, ее не может быть в принципе, до тех пор, пока весь код не будет верифицирован. Там же могут еще быть всякие милые сердцу вещи вроде FFI и всяких callback-ов из native потоков. В общем, до момента, пока великая система типов все верифицирует можно не дожить, а TSan есть уже сейчас.

CK>>Race condition же, или ты считаешь что data race это единственная разновидность race condition?

WH>Нет. Но остальные в нормальных языках прописываются явно. Те в коде ты одновременно ожидаешь событие из нескольких источников.

Define "нормальные языки". Пока получается такая цепочка рассуждений — data race очень опасная штука, потому что очень сложно найти источник проблемы, а race condition in general — нет, так как в "нормальных языках" (тм) ...

WH>1)Метод empty в очереди сообщений мягко говоря сомнителен.

WH>При нормальном дизайне там должен быть метод isClosed означающий что сообщений больше не будет.
WH>2)Доставка сообщений с гарантией — это отдельный большой вопрос.

Ну вот видишь, получается что просто нормальным дизайном можно избавиться от проблемы. Подумать явно о том что в фоне может что-то с очередью происходить и все. Тем не менее, если программист пишет межпоточную очередь с метдом empty, как ты его остановишь? Какая система типов запретит делать херню?

WH>>>Есть несколько разных систем типов которые убивают гонки с 100%ной гарантией.

CK>>Например?
WH>Раз: Re[13]: Языки для распараллеленных вычислений
Автор: WolfHound
Дата: 28.09.16


А как же накладные расходы на копирование/сериализацию/десериализацию?

CK>>Starvation/priority inversion, thundering herd, deadlock, livelock, lock contention (крайние проявления по крайней мере).

WH>Ещё раз. Это всё равно что заявлять, что статическая типизация не нужна, ибо позволяет написать вместо линейного алгоритма квадратичный.

Если ты предлагаешь какую-то модель вычислений в качестве решения проблемы, она должна решать не только эту проблему. Это мое IMO конечно, но то что ты предлагаешь (разделить кучи) это как раз такое вот решение, которое решает одну проблему и закрывает глаза на другие.
Re[19]: Языки для распараллеленных вычислений
От: WolfHound  
Дата: 03.10.16 19:43
Оценка:
Здравствуйте, chaotic-kotik, Вы писали:

CK>Ничего мы про него еще не выяснили.

Выяснили что ничего он не гарантирует.

CK>Define "нормальные языки". Пока получается такая цепочка рассуждений — data race очень опасная штука, потому что очень сложно найти источник проблемы, а race condition in general — нет, так как в "нормальных языках" (тм) ...

Если единственный способ получить гонку написать:
GetMessage(mailbox1, mailbox2, mailbox3...)
то проблем нет.

CK>Ну вот видишь, получается что просто нормальным дизайном можно избавиться от проблемы.

Только мы тут о других проблемах говорим.
И нормальный дизайн от ошибок по невнимательности не защищает.
А система типов именно это и делает. Причем гарантированно.

CK>Подумать явно о том что в фоне может что-то с очередью происходить и все. Тем не менее, если программист пишет межпоточную очередь с метдом empty, как ты его остановишь? Какая система типов запретит делать херню?

1)Никакая. Точно так же как никакая система типов не запретит вместо линейного алгоритма написать квадратичный.
2)Очередь должна быть в стандарной библиотеке. Так что 99.999% программистов её писать не будут.

WH>>Раз: Re[13]: Языки для распараллеленных вычислений
Автор: WolfHound
Дата: 28.09.16

CK>А как же накладные расходы на копирование/сериализацию/десериализацию?
Их нет. В пределах одного адресного пространства передача графа объектов из одного потока в другой на машинном уровне всегда сводится к передаче одного указателя.
Вся эта пляска с системами типов для этого и задумывалась.
... << RSDN@Home 1.0.0 alpha 5 rev. 0>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[16]: Языки для распараллеленных вычислений
От: vdimas Россия  
Дата: 05.12.16 15:52
Оценка:
Здравствуйте, WolfHound, Вы писали:

CK>>Есть класс дыр в безопасности, т.н. double fetch vulnerabilities вызванных именно race-ами, но ты едва ли сможешь избавиться от них с помощью системы типов.

WH>Есть несколько разных систем типов которые убивают гонки с 100%ной гарантией.

А если нам эти гонки принципиально нужны для lock-free алгоритмов?
Re[2]: Языки для распараллеленных вычислений
От: Pzz Россия https://github.com/alexpevzner
Дата: 05.12.16 22:57
Оценка:
Здравствуйте, VladD2, Вы писали:

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


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

VD>Правильные мысли есть в Расте. Но там все слишком сложно для того чтобы это могло войти в мэйнстрим. Нужно научить языки манипулировать кучами. Научить передавать эти кучи между "виртуальными процессами" (в стиле Эрланг).


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

Зачем нужно передавать кучи?

Странно, что ты не упомянул go.
Re[4]: Языки для распараллеленных вычислений
От: Pzz Россия https://github.com/alexpevzner
Дата: 05.12.16 23:05
Оценка:
Здравствуйте, VladD2, Вы писали:

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


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

VD>Грубо говоря нужны языки обеспечивающие дешевые паралельные процессы. И дешевую передачу данных между ними. Для этого нужны:

VD>1. Гарантией неизменности данных разных "процессах".

Функциональное программирование без побочных эффектов?

VD>2. Дешевизна передачи данных (заморозка графа объектов в одном процессе и передачи его в другой).


Заметим, что если данные не могут меняться, то передача их довольно дешевая. Но есть естественное ограничение, если данные передаются между кешами разных процессорных ядер, это не бесплатно на аппаратном уровне.
Re[3]: Языки для распараллеленных вычислений
От: VladD2 Российская Империя www.nemerle.org
Дата: 06.12.16 09:03
Оценка:
Здравствуйте, Pzz, Вы писали:

Pzz>Может ты и прав, но по-моему, основная проблема в том, что человек не очень умеет распараллеливать свои алгоритмы.


Многие и написать то их не в состоянии. Зачем равняться на идиотов? У меня как-то само распараллеливание проблем не вызывает. Человек отлично понимает где имеет смысл вводить параллелизм. В отличии от компьютера он понимает и держит в голове модель всего приложения и представляет какими данными человек манипулирует.

У компьютера же 100500 вариантов и выбрать оптимальный — неразрешимая, для него, задача.

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


"Рассказать" может и можно, но пока нет ИИ решить где надо параллелизм компьютер не сможет.

Он сможет выявить участки кода которые нельзя параллелить (т.е. должны выполняться последовательно). Но таких участков будет море. И еще не факт, что нужно весь этот участок параллелить, а не его часть.

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

Pzz>Раст, на мой (очень поверхностный) взгляд черезчур детальный. Слишком много слов надо сказать компилятору, чтобы выразить мысль. То, что многие из этих слов обозначаются двухбуквенными сокращениями, особо не помогает


В Расте отказались от ЖЦ чем усложнили программирование. Но в целом там есть правильные идеи. Лучше пока что ничего нет.

Pzz>Зачем нужно передавать кучи?


Для эффективности. Довольно распространенным паттерном является: формирование некоторого набора данных и передача его на обработку в другой поток/процесс (возможно даже удаленный).

Pzz>Странно, что ты не упомянул go.


Это тупейший язык не имеющий ничего интересного в области распараллеливания кода (если они ничего нового не придумали).
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[5]: Языки для распараллеленных вычислений
От: VladD2 Российская Империя www.nemerle.org
Дата: 06.12.16 10:25
Оценка:
Здравствуйте, Pzz, Вы писали:

Pzz>Мне кажется, конечное решение, что параллелить, а что нет, можно принять только в рантайме.


Из чего это вытекает? Я вот как-то без проблем параллелью код в во время проектирования.

Более того не очень ясно что делать в рантайме. Код то уже скомпилирован. В рантайме можно лишь решить в скольких потоках выполнять ту или иную функцию (в одном или в нескольких). Но сам код распараллеливания уже должен быть написан и распараллеливание функция должна быть выбрана. Или весь код будет каким-тол жутким интерпретатором.

Pzz>Человек должен иметь возможность выразить, что можно параллелить, но вот будет оно фактически распараллелено или нет, можно определить только в процессе исполнения.


Все с точностью до наоборот. На практике я точно знаю какие части программы имеет смысл распараллелить. А компьютер (компилятор, рантайм и т.п.) и понятия не имеет. Он туп.

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

По сему мне нужно иметь языковые средства которые бы разделяли работу с данными на два этапа:
1. Формирование.
2. Использование.

А компилятор должен помочь мне четко разделить эти этапы. На этапе формирования я могу императивно манипулировать данными, но исключительно из одного потока. На этапе использования я могу использовать данные из любого числа потоков, но менять их я уже не могу. Она для меня должны быть эдаким слепком.

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

В принципе аналогичных результатов можно добиться используя неизменяемые структуры данных и чисто функциональный стиль программирования. Но это:
1. Не всегда эффективно. Точнее — зачастую не эффективно.
2. Все равно есть необходимость подмены неизменяемых структур в разных потоках, а стало быть есть место для ошибки.

Pzz>Функциональное программирование без побочных эффектов?


Нельзя все сделать функционально. Это не эффективно. И это не всегда удобно. Плюс есть еще и внешние источники данных, а так же необходимость взаимодействия с внешними клиентами.

Классические задачи не ложащиеся на ФП:
1. Изменение баз данных.
2. Интерактивный UI.
3. Синхронизация действий внешних агентов (например, пользователей).

Pzz>Заметим, что если данные не могут меняться, то передача их довольно дешевая. Но есть естественное ограничение, если данные передаются между кешами разных процессорных ядер, это не бесплатно на аппаратном уровне.


Если данные не изменяются, то их можно и совместно в разных потоках использовать. Более того, можно создавать версии этих данных, которые используются как часть более новых версий данных Классический односвязный список — отличный пример такой версионности. Но, если в языке есть изменяемые структуры данных, то рано или поздно программист накосячит.

Более того при формировании данных куда эффективнее и удобнее использовать не только неизменяемые структуры, но и "обычные" изменяемые. Например, хэш-таблицу. Но передавать такие данные опасно. Графы же объектов, которые надо передавать, могут быть очень сложными. И вручную проконтролировать, что их части не изменяются случайно в другом потоке невозможно.

Можно конечно тупо клонировать весь граф объектов, но это дорого для многих применений.

Дешевле условно разбить процесс на два:
1. Формирование данных.
2. Использование.

Если заставить компилятор и рантайм контролировать:
1. Отсутствие параллельного доступа на этапе 1 (формирования).
2. Невозможность изменять данные на этапе 2 (использования).

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

Такие блоки данных можно помещать в отдельные кучи. А в язык можно добавить средствам манипуляции целыми кучами. За одно это решило бы и проблему не эффективности GC. Так как GC мог бы манипулировать не всеми данными в процессе, а отдельными кучами. За одно было бы проще решать и проблему утечки памяти. Ведь человек может четка определить, что в такой то момент времени ссылок на некоторую кучу быть не должно. И если они есть — это ошибка. Остается только разобраться что не так.

Переключать режимы Формирование/Использование в куче будет очень удобно и просто.

Но для такого подхода нужна поддержка в языке и рантайме. По объекту нужно иметь возможность определить из какой кучи выделен объект и в каком состоянии находится эта куча. В типах указателей так же должна быть информация о режиме в котором находится объект (куча). Нечто похожее на C++-ый const.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[17]: Языки для распараллеленных вычислений
От: WolfHound  
Дата: 07.12.16 10:38
Оценка:
Здравствуйте, vdimas, Вы писали:

WH>>Есть несколько разных систем типов которые убивают гонки с 100%ной гарантией.

V>А если нам эти гонки принципиально нужны для lock-free алгоритмов?
Язык и стандартная библиотека с большим запасом покроют потребности примерно 100% пользователей.
А те пара человек, которым не хватит используют unsafe.
И это если не вспоминать о том, что примерно 99% программистов lock-free структуру данных написать не смогут.
... << RSDN@Home 1.0.0 alpha 5 rev. 0>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[6]: Языки для распараллеленных вычислений
От: WolfHound  
Дата: 07.12.16 10:38
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Более того не очень ясно что делать в рантайме. Код то уже скомпилирован. В рантайме можно лишь решить в скольких потоках выполнять ту или иную функцию (в одном или в нескольких). Но сам код распараллеливания уже должен быть написан и распараллеливание функция должна быть выбрана. Или весь код будет каким-тол жутким интерпретатором.

Не обязательно. Можно перекомпилировать код в рантайме как это делают некоторые реализации явы.

VD>Все с точностью до наоборот. На практике я точно знаю какие части программы имеет смысл распараллелить. А компьютер (компилятор, рантайм и т.п.) и понятия не имеет. Он туп.

Лет 10-15 назад говорили, что руками на ассемблере код получится быстрее чем у компилятора.
Сейчас только упоротые пытаются соревноваться с лучшими компиляторами.
Что получится с автоматическим распараллеливанием будем посмотреть, но от категоричных высказываний лучше воздержаться.

VD>А компилятор должен помочь мне четко разделить эти этапы. На этапе формирования я могу императивно манипулировать данными, но исключительно из одного потока. На этапе использования я могу использовать данные из любого числа потоков, но менять их я уже не могу. Она для меня должны быть эдаким слепком.

Система типов о которой я говорю именно это и делает.
def (p1, p2,...) = makeimmutable(oldP1, oldP2,...);

После это строки ссылки на изменяемые структуры данных oldP1, oldP2,... становятся не доступны.
p1, p2,... и всё на что они ссылаются можно использовать имея гарантию что они никогда не будут изменены.

В случае с нитрой идеально подходит для композитных грамматик.

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

Тут придётся немного усложнить систему типов и использование таких структур будет создавать шум в виде read lock/write lock и некоторые другие ограничения. Но тоже возможно.
def (lp1, lp2,...) = makelockable(oldP1, oldP2,...);

lp1, lp2,... контейнеры содержащие ссылку на примитив синхронизации и указатель на данные. Сами контейнеры являются неизменяемыми для того чтобы можно было положить их в неизменяемую структуру данных.
read lock (p1 = lp1)
{
//тут можно читать содержимое структуры данных
}
//тут все ссылки полученные из структуры станут недоступны

тоже самое с write lock но структуру данных можно ещё и изменять.

В случае с нитрой можно использовать для АСТа, деклараций итп.

VD>Если заставить компилятор и рантайм контролировать:

VD>1. Отсутствие параллельного доступа на этапе 1 (формирования).
VD>2. Невозможность изменять данные на этапе 2 (использования).
Достаточно компилятора.

VD>Такие блоки данных можно помещать в отдельные кучи. А в язык можно добавить средствам манипуляции целыми кучами. За одно это решило бы и проблему не эффективности GC. Так как GC мог бы манипулировать не всеми данными в процессе, а отдельными кучами.

О чем я тебе уже сколько лет говорю?

VD>Переключать режимы Формирование/Использование в куче будет очень удобно и просто.

формирование -> заморозка
Действительно удобно и просто.

формирование -> использование -> изменение -> использование -> изменение -> ...
Неизбежно потребует дополнительных приседаний.
... << RSDN@Home 1.0.0 alpha 5 rev. 0>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.