Здравствуйте, gandalfgrey, Вы писали:
G>Это реализация изначально кривого подхода — ибо затачиваться на последовательность действий вредно и опасно.
ага, это изначально реализация дедлока . достаточно запустить dl:start(). и вуаля
а у тебя код красивый, но не рабочий пока
что или как запускать-то чтобы заработало-то в смысле за дедлочило
можно по слогам
Здравствуйте, Nicht, Вы писали:
DSG>>Достатки MPI, к примеру, — не нужно писать код синхронизации, нету дедлоков. Вообще подход написания другой. N>А в erlang прям "Дивный новый мир". Простой пример. есть у меня адрес и индекс. Понятно что они всегда толжны соответствовать друг другу. Как в таком случае без синхронизации? (Пример гипотетический — так что не придерайся). Опять же, повторюсь что вся эта erlang модель в java да и везде, называется Compare and Set.
Эта erlang модель называется "гармонично взаимодействующие процессы" и придумана Дийкстрой, или более точно для erlang, она называется actors model. В яве вашей модель называется wait-notify, и придумана Хоаром — и она более безопасна, чем семафоры-мутексы, которые, кстати, тоже придумал Дийкстра. Есть другие модели синхронизации и параллельного взаимодействия, скажем, барьерная синхронизация, механизм рандеву, joint-calculus, etc. Все модели выразимы друг через друга, то есть эквивалентны, и этот факт доказан. Что ровным счетом ничего не меняет в контексте заданного автором вопроса.
Фундаментальное отличие actors model и гармонично взаимодействующих процессов" от всего остального в том, что они не имеют разделяемых данных, и связанных с ними проблем в принципе.
Compare-and-set — вообще никакая не модель, это процессорная инструкция, на которую полагаются lock-free data structures. В случае, разумеется, разделяемых данных, которых в actors model нет.
Еще раз повторяться вам, мне кажется, не стоит. А то народу может и надоесть.
Здравствуйте, abch-98-ru, Вы писали:
A9R>а у тебя код красивый, но не рабочий пока A9R>что или как запускать-то чтобы заработало-то в смысле за дедлочило A9R>можно по слогам
-module(dl).
-export([start/0,sem/0,start_two/2]).
sem()->sem(none,{"",""}).
sem(State,{Txt,Id}=Mess) ->
receive
{take, A} when State==none->
A ! {taken, self()},
sem(taken,{"take",""});
{free, A} when State==taken->
A ! {freed, self()},
sem(none,{"free",A})
after 3000->
io:fwrite("timeout dl with ~p ~s ~n", [Id,Txt]),
sem(none,{"",""})
end.
start_two(P1,P2)->
P1 ! {take, self()},
two(none,P1,P2,"~p ~p~n").
two(State,P1,P2,Mess) ->
receive
{taken, P1} when State==none->
timer:sleep(1000),
P2 ! {take, self()},
two(take,P1,P2,"!!!DEADLOCK!!! taken ~p cant take ~p ~n");
{taken, P2} when State==take->
timer:sleep(1000),
P2 ! {free, self()},
P1 ! {free, self()},
two(none,P1,P2,"cant take ~p, nor ~p ~n")
after 5000->
io:fwrite(Mess,[P1,P2]),
two(none,P1,P2,"~p ~p~n")
end.
start() ->
P1 = spawn (?MODULE, sem, []),
P2 = spawn(?MODULE, sem, []),
spawn(?MODULE, start_two, [P1,P2]),
spawn(?MODULE, start_two, [P2,P1]).
Здравствуйте, Gaperton, Вы писали:
G>Фундаментальное отличие actors model и гармонично взаимодействующих процессов" от всего остального в том, что они не имеют разделяемых данных, и связанных с ними проблем в принципе.
...они не имеют разделяемых данных, и связанных с ними проблем и преимуществ в принципе.
Я думаю, так будет честнее. Кстати, никто не запрещает комбинировать актёров и разделяемые данные (с умом, естественно), беря от обоих моделей лучшее.
Здравствуйте, yumi, Вы писали:
R>>Не понял смысл аналогии с ассемблером. Давай более конкретно. Вот
Y>Этим я хотел выразить такую мысль, что Эрланг предоставляет наиболее высокий уровень абстракции при работе с многопоточными приложениями.
R>>Вот функция без побочных эффектов, которая используется при распараллеливании: R>>
R>>void func(int* a, int* b, int begin, int end)
R>>{
R>> for (int i = begin; i != end; ++i)
R>> a[i] += b[i];
R>>}
R>>
R>>Какие тут проблемы?
Y>А то, что тут как раз явный побочный эффект торчит, тебя не смущает? То есть при выполнении этой функции в отдельном потоке, у тебя где-то еще в другом потоке, может изменяться твой массив 'a', разве это не проблема?
Абсолютно не смущает. Это даже к лучшему — класс эффективно распараллеливаемых функций шире класса функций без побочных эффектов, и если можно этим воспользоваться, то это — хорошо.
Если измениться в другом потоке? Ну, я думаю, будет то же, что и если бы функцию без побочных эффектов применили 2 раза вместо одного — т.е. ошибка в программе. К счастью (хотя вполне логично), библиотеки поддержки параллелизма не будут вызывать функции над одними данными из разных потоков. Смысл?
Y>Теперь безотносительно побочного эффекта и связанных с ней проблем. По моим сугубо религиозным взглядам, твой пример должен параллелиться автоматически компилятором, средой, а не вручную как это делаешь ты. Попробую обосновать, когда ты это делаешь вручную, ты привязываешься на фиксированное количество ядер/процессоров
Не правильно... ну или смотря, что называть ручным распараллеливанием. Я называю что-то типа такого:
#pragma omp parallel for schedule(dynamic, 256)
for (...)
Вся интеллектуальная часть (самое сложное) ложится на программиста. Вся рутинная работа (в т.ч. подгон под кол-во ядер) — на ран-тайм.
Y>(хотя конечно можно вручную тоже это рулить, но это тот еще геморрой). Поэтому я считаю, что такой код должен быть распараллелен компилятором, средой. По одной простой причине, что среде исполнения будет известно количество ядер/процессоров на которой исполняется твоя программа и она сможет эффективно ее распараллелить для конкретной машины. Например, твой пример для одно ядерной машины будет эффективнее выполнить целиком, то бишь передать: begin = 0, end = lenght — 1. А для двух ядерной машинки в два потока: (begin = 0, length/2) и (begin = length/2 + 1, end = length — 1).
Рутинные-то операции компилятор/ран-тайм могут сделать, в т.ч. учитывая число ядер. Проблема в том, что они не могут сделать интеллектуальную часть.
А всё полностью делать руками никто особо и не призывает... ну кроме разве что самых специфических случаев.
R>>Мммм... ну и как в Эрланге работать с общей памятью?
Y>См. mnesia.
Какая связь между DBMS и shared memory?
Y>>>Напиши. Вся проблема в том, что ты этого не напишешь.
R>>Мммм... даже не знаю, что ответить... Разве что я уже две написал. И работал с рядом проектов, которые активно использовать передачу сообщений, хотя и до актёр-ориентированных не дотягивали. R>>Написать рабочую базовую версию — на это надо примерно 1 день. А дальше полная свобода действий. Хочешь вставляешь логирование всех проходящих сообщений, хочешь делаешь специальную фильтрацию при широковещательных рассылках, хочешь делаешь перехватчики сообщений, хочешь делаешь диспетчиризацию при отправке, хочешь при получении, хочешь делаешь reader-writer агенты и т.д.
Y>Я имел ввиду Erlang style concurrency с такими же TTX.
Так в том-то и суть, что это не надо писать. Базовая часть естественно нужна. Что-то нужно, но не с такими ТТХ, а с меньшими. Что-то нужно, но с лучшими ТТХ. Что-то не нужно вообще. Что-то нужно, чего нет в Эрланг. И не всё из этого нужно сразу.
Y>Кстати уж больно ты мне одного товарища напоминаешь, ты случаем не с софтового отдела Intel'а?
Здравствуйте, cadet354, Вы писали:
C>Я особенно глубоко не разбирался с ССR (видимо зря), не подскажешь как сделать такую вещь как очередь с приоритетом, причем приоритет определяться по определенному полю в обьекте, его значению, грубо говоря больше/меньше определенного параметра.
Как там это сделать по-правильному не скажу. Возможно самое простое решение — завести 2 порта (очереди), каждая очередь под сообщения своего приоритета.
Здравствуйте, remark, Вы писали:
R>Здравствуйте, Gaperton, Вы писали:
G>>Фундаментальное отличие actors model и гармонично взаимодействующих процессов" от всего остального в том, что они не имеют разделяемых данных, и связанных с ними проблем в принципе.
R>...они не имеют разделяемых данных, и связанных с ними проблем и преимуществ в принципе.
R>Я думаю, так будет честнее. Кстати, никто не запрещает комбинировать актёров и разделяемые данные (с умом, естественно), беря от обоих моделей лучшее.
Здравствуйте, Курилка, Вы писали:
К>Здравствуйте, remark, Вы писали:
R>>Здравствуйте, Gaperton, Вы писали:
G>>>Фундаментальное отличие actors model и гармонично взаимодействующих процессов" от всего остального в том, что они не имеют разделяемых данных, и связанных с ними проблем в принципе.
R>>...они не имеют разделяемых данных, и связанных с ними проблем и преимуществ в принципе.
R>>Я думаю, так будет честнее. Кстати, никто не запрещает комбинировать актёров и разделяемые данные (с умом, естественно), беря от обоих моделей лучшее.
К>Или получая проблемы из обоих моделей
Ну плохое-то сделать это на любом языке и при любой технологии — не проблема... Но меня это не особо интересует. Меня интересует как сделать хорошо — соотв. я и предлагаю комбинировать с умом и брать лучшее.
Здравствуйте, remark, Вы писали:
R>Здравствуйте, Gaperton, Вы писали:
G>>Фундаментальное отличие actors model и гармонично взаимодействующих процессов" от всего остального в том, что они не имеют разделяемых данных, и связанных с ними проблем в принципе.
R>...они не имеют разделяемых данных, и связанных с ними проблем и преимуществ в принципе.
R>Я думаю, так будет честнее. Кстати, никто не запрещает комбинировать актёров и разделяемые данные (с умом, естественно), беря от обоих моделей лучшее.
Так будет не честнее, потому, что преимущество очевидно есть. Акторы гораздо, существеннее устойчивее к латентности системы. К тому же, в ряде случаев у тебя общей памяти натурально нет, и что удивительно, именно тогда, когда высока латентность каналов связи. Возьми кластер, связанный гигабитным ethernet. Что будем делать? Эмулировать общую память (словив огромную латентность)? Знаешь, какая именно просадка в производительности у тебя получится?
Здравствуйте, Gaperton, Вы писали:
G>Здравствуйте, remark, Вы писали:
R>>Здравствуйте, Gaperton, Вы писали:
G>>>Фундаментальное отличие actors model и гармонично взаимодействующих процессов" от всего остального в том, что они не имеют разделяемых данных, и связанных с ними проблем в принципе.
R>>...они не имеют разделяемых данных, и связанных с ними проблем и преимуществ в принципе.
R>>Я думаю, так будет честнее. Кстати, никто не запрещает комбинировать актёров и разделяемые данные (с умом, естественно), беря от обоих моделей лучшее.
G>Так будет не честнее, потому, что преимущество очевидно есть. Акторы гораздо, существеннее устойчивее к латентности системы. К тому же, в ряде случаев у тебя общей памяти натурально нет, и что удивительно, именно тогда, когда высока латентность каналов связи. Возьми кластер, связанный гигабитным ethernet. Что будем делать? Эмулировать общую память (словив огромную латентность)? Знаешь, какая именно просадка в производительности у тебя получится?
Это просто не тот случай, когда у разделяемой памяти есть приемущества. Зачем его вообще в таком контексте приводить???
Разделяемая память будет иметь приемущества в некоторых ситуацяиях на HT/CMT/HWT, multicore, SMP, SMP-NUMA. И тут она может дать приемущества как по скорости так и по латентности. Особенно целесообразна разделяемая память для небольших операций.
По поводу кластера, между узлами кластера разделяемой памяти нет (DSM не в счёт) поэтому тут и говорить особенно нечего. А вот внутри узлов кластера — другое дело. Например стандартная практика применять между узлами кластера MPI (обмен сообщениями), а внутри узлов — OpenMP (разделяемая память), просто потому что так получается значительно быстрее и проще.
Здравствуйте, remark, Вы писали:
G>>Так будет не честнее, потому, что преимущество очевидно есть. Акторы гораздо, существеннее устойчивее к латентности системы. К тому же, в ряде случаев у тебя общей памяти натурально нет, и что удивительно, именно тогда, когда высока латентность каналов связи. Возьми кластер, связанный гигабитным ethernet. Что будем делать? Эмулировать общую память (словив огромную латентность)? Знаешь, какая именно просадка в производительности у тебя получится?
R>Это просто не тот случай, когда у разделяемой памяти есть приемущества. Зачем его вообще в таком контексте приводить???
Ну надо же, откуда-то вдруг какие-то преимущества нарисовались, которых у разделяемой памяти нет. Зачем? Затем, что чуть выше ты сказал:
R>>>...они не имеют разделяемых данных, и связанных с ними проблем и преимуществ в принципе. R>>>Я думаю, так будет честнее.
Помнишь, что ты мне сказал? Теперь поступи так, как считаешь что будет честнее. Скажем, признай, что погорячился. Как вариант.
Здравствуйте, Gaperton, Вы писали:
G>Возьми кластер, связанный гигабитным ethernet. Что будем делать? Эмулировать общую память (словив огромную латентность)? Знаешь, какая именно просадка в производительности у тебя получится?
Вариант вполне рабочий, кстати. Это даже автоматизируется с помощью Terracotta, например. Естественно, оно не применимо на ВСЕХ задачах. Но это и не нужно..
Здравствуйте, Cyberax, Вы писали:
C>Здравствуйте, Gaperton, Вы писали:
G>>Возьми кластер, связанный гигабитным ethernet. Что будем делать? Эмулировать общую память (словив огромную латентность)? Знаешь, какая именно просадка в производительности у тебя получится? C>Вариант вполне рабочий, кстати. Это даже автоматизируется с помощью Terracotta, например. Естественно, оно не применимо на ВСЕХ задачах. Но это и не нужно..
Знаю, что рабочий. Берется низколатентная сеть, например InfiniBand, эмулируется общая память, и потом любуемся на график производительности. Херово он себя ведет. Умножение матриц на MPI с явно выделенными блоками на том же infiniband масштабируется значительно лучше, чем ты получишь на эмулированной общей памяти. Причина? Манипулируя сообщениями, ты выделяешь локальность данных. Вынужден. Оперируя общей памятью, тебе типа об этом можно не думать. Со всеми вытекающими.
Здравствуйте, Gaperton, Вы писали:
G>Знаю, что рабочий. Берется низколатентная сеть, например InfiniBand, эмулируется общая память, и потом любуемся на график производительности. Херово он себя ведет. Умножение матриц на MPI с явно выделенными блоками на том же infiniband масштабируется значительно лучше, чем ты получишь на эмулированной общей памяти. Причина? Манипулируя сообщениями, ты выделяешь локальность данных. Вынужден. Оперируя общей памятью, тебе типа об этом можно не думать. Со всеми вытекающими.
Я вот использую систему с "общей памятью" (распределённым кластерным кэшем) для кэширования данных. Подавляющая часть операций — это чтение, которое замечательно выполняется без всяких кластерных блокировок. Прекрасно работает даже на сравнительно высоколатентном Ethernet'е.
Здравствуйте, remark, Вы писали:
R>Это просто не тот случай, когда у разделяемой памяти есть приемущества. Зачем его вообще в таком контексте приводить??? R>Разделяемая память будет иметь приемущества в некоторых ситуацяиях на HT/CMT/HWT, multicore, SMP, SMP-NUMA. И тут она может дать приемущества как по скорости так и по латентности. Особенно целесообразна разделяемая память для небольших операций.
Я не вполне понимаю, что имеется в виду под "разделяемой памятью" и "неразделяемой памятью".
Какое именно преимущество есть у разделяемой памяти?
Отсутствие копирования? Ну так если у нас есть "передача владения", то среда может эмулировать эффекты приватной памяти без копирования.
Хочется понять, какие неотъемлемые проблемы есть у неразделяемой памяти.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, remark, Вы писали:
R>Как там это сделать по-правильному не скажу. Возможно самое простое решение — завести 2 порта (очереди), каждая очередь под сообщения своего приоритета.
да нет, надо чтоб если есть в очереди сообщения с определенном признаком, то их обработать в первую очередь, причем клиенты (те кто посылают сообщения о приоритетах мало что знают).
Т.е. прогнать текущую очередь, выбрать нужные, обработать, потом обрабатывать остальные в порядке получения, в ерланге это выглядит так:
priority_receive() ->
receive
{alarm, X} ->
{alarm, X}
after 0 ->
receive
Any ->
Any
end
end.
Здравствуйте, cadet354, Вы писали:
C>Здравствуйте, remark, Вы писали:
R>>Как там это сделать по-правильному не скажу. Возможно самое простое решение — завести 2 порта (очереди), каждая очередь под сообщения своего приоритета. C>да нет, надо чтоб если есть в очереди сообщения с определенном признаком, то их обработать в первую очередь, причем клиенты (те кто посылают сообщения о приоритетах мало что знают). C>Т.е. прогнать текущую очередь, выбрать нужные, обработать, потом обрабатывать остальные в порядке получения, в ерланге это выглядит так: C>
C>priority_receive() ->
C> receive
C> {alarm, X} ->
C> {alarm, X}
C> after 0 ->
C> receive
C> Any ->
C> Any
C> end
C> end.
C>
C>копирайты Армстронга.
Не подскажу, как такое смоделировать... там вроде ещё упоминалась возможность вручную создавать фильтры, может так можно... а может и что встроенное есть. Кстати, там по-моему совсем на днях новая версия вышла.
Здравствуйте, Gaperton, Вы писали:
G>>>Так будет не честнее, потому, что преимущество очевидно есть. Акторы гораздо, существеннее устойчивее к латентности системы. К тому же, в ряде случаев у тебя общей памяти натурально нет, и что удивительно, именно тогда, когда высока латентность каналов связи. Возьми кластер, связанный гигабитным ethernet. Что будем делать? Эмулировать общую память (словив огромную латентность)? Знаешь, какая именно просадка в производительности у тебя получится?
R>>Это просто не тот случай, когда у разделяемой памяти есть приемущества. Зачем его вообще в таком контексте приводить???
G>Ну надо же, откуда-то вдруг какие-то преимущества нарисовались, которых у разделяемой памяти нет. Зачем? Затем, что чуть выше ты сказал:
R>>>>...они не имеют разделяемых данных, и связанных с ними проблем и преимуществ в принципе. R>>>>Я думаю, так будет честнее.
G>Помнишь, что ты мне сказал? Теперь поступи так, как считаешь что будет честнее. Скажем, признай, что погорячился. Как вариант.
Я надеюсь, это шутка?
Очевидные и широко-известные приемущества разделяемой памяти — это (1) скорость работы и (2) низкая латентность.
Сравни 1 сохранение/загрузку из памяти против оверхеда на полный цикл 2 сообщений (запрос-ответ). 2 сообщения — это как минимум 2 записи в разделяемую память + 2 чтения из разделяемой памяти + 2 переключения контекста + в реальности значительно больше оверхеда (динамическая аллокация памяти, освобождениие памяти, копирования, добавления/извлечения из очереди).
А таком контексте вопрос по поводу факта наличия преимуществ у разделяемлой памяти меня просто шокирует.
Ну и так же есть преимущество в виде синхронного получения результата. Даже в Эрланге это (асинхронные сообщения) порождает некоторый синтаксический оверхед, а в большинстве языков необходимость в череде вызовов, на которые необходимы ответы для продолжения выполнения, — это просто @#$%^. Обычный вызов функции с синхронным получением результата для такого кода — это как манна с неба.
Здравствуйте, Sinclair, Вы писали:
R>>Это просто не тот случай, когда у разделяемой памяти есть приемущества. Зачем его вообще в таком контексте приводить??? R>>Разделяемая память будет иметь приемущества в некоторых ситуацяиях на HT/CMT/HWT, multicore, SMP, SMP-NUMA. И тут она может дать приемущества как по скорости так и по латентности. Особенно целесообразна разделяемая память для небольших операций.
S>Я не вполне понимаю, что имеется в виду под "разделяемой памятью" и "неразделяемой памятью". S>Какое именно преимущество есть у разделяемой памяти? S>Отсутствие копирования? Ну так если у нас есть "передача владения", то среда может эмулировать эффекты приватной памяти без копирования. S>Хочется понять, какие неотъемлемые проблемы есть у неразделяемой памяти.