English | 中文 | Русский | Français
409 Тем для обсуждения
4,160 Открытых обсуждений
В заголовок этого поста вынесено начало эпиграфа к книге K.Mani Chandy, Jayadev Misra “Parallel Program Design: A Foundation”. Полностью этот эпиграф выглядит так:
“The most general definition of beauty … Multeity in Unity”
(Samuel Taylor Coleridge, “On the Principles of Genial Criticism”, 1814).
К чему это?
Хотелось бы еще на одном примере показать, как грамотно выбранная система обозначений (читай, язык программирования) позволяет очень просто сформулировать алгоритм решения задачи, который в другой бы нотации записывался очень сложно, или, вообще бы казался нереализуемым.
Начнем чуть издалека. Многим хорошо известен язык логического программирования Prolog, программирование на котором в чистом виде состоит в том, что мы, в основном, выписываем правила того, ЧТО должно быть сделано для решения задачи, оставляя вопрос КАК это делать интерпретатору этого языка. Т.е., интерпретатор языка Prolog выполняет любую программу единым образом – пытается сделать истинными предложения, из которых составлена программа, используя, возможно, откаты назад (так называемый бектрекинг).
Существует довольно широкий класс задач, которые также можно решать некоторым единым способом. Это класс задач для которых решение находится с помощью итерационного процесса, который останавливается когда система перешла в некоторое стабильное состояние, или достигла, как говорят, некоторой неподвижной точки.
В упомянутой выше книге, излагается формализм для представления (программирования) такого рода задач – введена программная нотация и разработаны теоретические методы рассуждений (логика) о программах, записанных в данной нотации. Весь этот подход получил название Unity. Следует заметить, что указанная книга и сопутствующие статьи составляют один из краеугольных камней науки о параллельном программировании, наряду с работами Хоара, Дейкстры и Милнера.
Язык программирования Unity понять очень легко – мы его продемонстрируем на примере записи программы нахождения наибольшего общего делителя двух целых чисел:
Program gcd
declare x, y : integer
initially x, y = X, Y
assign
x, y := x – y, y if x > y
| x, y := x, y – x if y > x
end { gcd }
Выполняется программа такого вида следующим образом: выбирается и вычисляется одно из присваиваний, для которого истинно условие выполнения. Если таких присваиваний несколько, то (недетерминированно) выбирается для исполнения только одно из них. Если таких присваиваний нет, то программа останавливается. Такого рода итерации продолжаются до тех пор, пока не наступит стабильное состояние – значения переменных на очередной итерации совпадут с предыдущими их значениями. (Более практические вопросы – ввод/вывод, модуляризация, и т.д. здесь, в иллюстративных целях, опущены). Заметим также, что данная нотация является внутренне параллельной – вычисление выражений, разделенных запятыми, в правой части присваиваний может выполняться одновременно. В частности, в указанной выше книге имеется несколько разделов, посвященных реализации этой модели вычислений на различных параллельных архитектурах – системах с передачей сообщений, систолических массивах, и т.п.
Теперь реализуем с помощью Unity модель некоторой системы, которая обсуждалась в комментариях к моим двум предыдущим постам. А именно, требуется реализовать в виде двух параллельных процессов модели логических элементов И-НЕ, связанных между собой перекрестными связями. А именно, выход y1 первого элемента вычисляется как
y1 = NOT ( x1 AND y2 ),
а выход y2 второго элемента вычисляется как
y2 = NOT ( x2 AND y1 ).
Как работает данная система – было проанализировано “на бумажке” в комментариях к предыдущим постам. Чтобы получить аналогичное поведение, мы просто напросто переносим определение системы в формализм Unity:
Program Model
declare x1, x2, y1, y2 : integer
initially x1, x2, y1, y2 = 0, 0, 0, 0
assign
y1, y2 = 1- ( x1 & y2 ), 1 - ( x2 & y1 )
end { Model }
Программа (причем, параллельная) получена!
И как вам это?
PS
Всех с наступающим Новым годом !
И в качестве альбома для прослушивания на Новый год рекомендую
один из лучших дисков 2007 года – Burial “Untrue”
| 17.01.2009 10:52
YurySerdyuk |
В силу непрекращающихся дискуссий (см. другие посты данного блога и комментарии к ним), ниже приводится решение сформулированной выше задачи на языке MC#: using System; public class Model { public static void Main ( String[] args ) { int y1 = 0; // Initial int y2 = 0; // state Model md = new Model(); md.AND_NOT ( 1, y1, y2, md.getX1, md.getY2, md.Y1, md.result1 ); md.AND_NOT ( 2, y2, y1, md.getX2, md.getY1, md.Y2, md.result2 ); md.X1 ! ( 0 ); md.X2 ! ( 0 ); md.print ? (); md.X1 ! ( 1 ); md.X2 ! ( 0 ); md.print ? (); md.X1 ! ( 0 ); md.X2 ! ( 1 ); md.print ? (); md.X1 ! ( 1 ); md.X2 ! ( 1 ); md.print ? (); } ///////////////////////////////////////////////////////////////// public handler getY1 int() & channel Y1 ( int x ) { return x; } public handler getY2 int() & channel Y2 ( int x ) { return x; } public handler getX1 int() & channel X1 ( int x ) { return x; } public handler getX2 int() & channel X2 ( int x ) { return x; } /////////////////////////////////////////////////////////////////// public handler print void() & channel result1 ( int y1 ) & channel result2 ( int y2 ) { Console.WriteLine ( "Y1 = " + y1 + " Y2 = " + y2 ); } ///////////////////////////////////////////////////////////////////////////////////////// public async AND_NOT ( int myNumber, int initial_output, int initial_feedback, handler int () getInput, handler int () getFeedback, channel (int) output, channel (int) sendResult ) { int output_old, output_new; int feedback_old, feedback_new; int input; bool continue_iterations; output_old = initial_output; feedback_old = initial_feedback; while ( true ) { input = (int) getInput ? (); continue_iterations = true; while ( continue_iterations ) { output_new = 1 - ( input & feedback_old ); output ! ( output_new ); feedback_new = (int) getFeedback ? (); if ( output_old == output_new && feedback_old == feedback_new ) { continue_iterations = false; output_old = output_new; feedback_old = feedback_new; sendResult ! ( output_old ); } else { output_old = output_new; feedback_old = feedback_new; } } } } } |
| 18.01.2009 21:15
vlubch |
Лично мне не показалось что-то "красивым" в Unity, т.к. … 1. Неужели нельзя записать параллельные операторы естественно, т.е. так, как дано в постановке? 2. Видимо, выражение «1- …» заменяет операцию отрицания? Т.е. программа на Unity пока «никак» :) Я уж не говорю о том, что надо еще убедиться, что все работает правильно. В смысле проверки меня больше привлекает программа на MC#. Но Вы сами, Юрий, ее проверяли? Мне так и не удалось ее скомпилировать. «Фибоначчи» из демо идет, а данная программа нет. В чем дело? И еще. Можно ли заодно и переписать программу так, чтобы ввод значений x1, x2 был организован из массива? |
| 19.01.2009 13:26
YurySerdyuk |
>1. Неужели нельзя записать параллельные операторы естественно, т.е. так, как дано в постановке? Операторы записаны в точности как в постановке задачи: а)в постановке - y1 = !(x1&y2); y2 = !(x3&y1); б) в формализме Unity - y1, y2 = 1- ( x1 & y2 ), 1 - ( x2 & y1 ) ( в точности до замены операции отрицания операцией вычитания из единицы, чтобы иметь значения y1 и y2 целочисленного типа, а не логического, как в постановке задачи). >Но Вы сами, Юрий, ее проверяли? Неужели Вы думаете, что я выставил неотлаженную программму :-) ? >Мне так и не удалось ее скомпилировать. «Фибоначчи» из демо идет, а данная программа нет. В чем дело? По конкретным вопросам пишите на info (at) mcsharp.net - поможем ... >Можно ли заодно и переписать программу так, чтобы ввод значений x1, x2 был организован из массива? Естественно - просто зациклите фрагмент программы вида md.X1 ! ( 0 ); md.X2 ! ( 0 ); md.print ? (); md.X1 ! ( 1 ); md.X2 ! ( 0 ); md.print ? (); md.X1 ! ( 0 ); md.X2 ! ( 1 ); md.print ? (); md.X1 ! ( 1 ); md.X2 ! ( 1 ); md.print ? (); так, чтобы значения для входных каналов X1 и X2 брались из массива. |
| 25.01.2009 00:29
vlubch |
Неестественность решения Unity просто режет глаза… Например, 1. Если бы мне нужно было бы добавить еще один оператор (пусть это будет оператор, выполняющий некоторые действия с переменными y1,y2), то в естественной постановке это было бы так: y1 = !(x1&y2); y2 = !(x3&y1); y3 = !(y1&y2); (К примеру, на языке VHDL все это фактически так и будет) На Unity должно быть, видимо так: y1, y2, y3 = 1- ( x1 & y2 ) , 1 - ( x2 & y1 ), 1 - ( y1 & y2 ) Я правильно понял "естественность" Unity? Если это так, то это весьма удручает. Что же красивого и естественного в таком подходе (или еще лукавее – системе кодирования)? :) А зачем иметь y1 и y2 только целочисленного типа? Все это в сумме какая-то своеобразная «естественность» и… «красивость» :) 2. О программе на MC#. А если у меня массив из 100, 1000 и т.д. элементов?... Тоже циклить «фрагмент»? И будут ли выполняться операторы, которые не входят в этот цикл, если я его сделаю «вечным»? Я скопировал весь код на MC# в блокнот, изменил расширение файла и пропустил код через систему MC#. Я не добавил ни одного символа! Что я сделал не так? Кстати и естественность MC# вызывает множество вопросов... |
| 25.01.2009 16:39
YurySerdyuk |
Во-первых, Вы переводите разговор в обсуждение качественного понятия "естественность", хотя до сих пор настаивали на __невозможности__ реализации предложенного примера. Реализация на Unity корректна ? Очевидно, что - "да" ... >А зачем иметь y1 и y2 только целочисленного типа? Потому что логический тип (bool) - это значения true и false, а целочисленный - это значения 0,1, ... В Вашем объяснении на бумажке использовался целочисленный тип, он же использован и в реализации. >Что я сделал не так? Второй раз повторяю - высылайте конкретный протокол по указанному адресу, и мы Вам поможем ... |
| 25.01.2009 23:34
vlubch |
Какой-то странный «газовый диалог» у нас с Вами, Юрий, получается… :) И хотя он затягивается, но я повторю еще раз. 1) Если бы Вы написали в «системе кодирования» Unity также, как написали, обсуждая модель, то не было бы вопроса о «естественности». Нужна-то самая малость: от записи модели в виде: y1 = NOT ( x1 AND y2 ), y2 = NOT ( x2 AND y1 ), вставить на Unity что-то типа (если возможно, конечно): … y1 = 1- ( x1 & y2 ) y2 = 1 - ( x2 & y1 ) … Только такая «естественность» позволяет «качественно» решать проблемы внесения изменения в код (см. о добавлении еще одного оператора y3). Меня удивляет то, что Вы этого как бы не понимаете. 2) Бог с ними типами, но было бы намного понятнее, если бы на Unity было примерно следующее: … y1 = !( x1 & y2 ) y2 = !( x2 & y1 ) … Вычитание из «1», скажем так, сильно смущает. 3) О корректности. О ней можно говорить лишь только убедившись, что … «газ пошел» :). До этой поры все «бумажки» годятся лишь на растопку. Для полной корректности нужно иметь не только корректную запись, но и корректную работу. Буга все стерпит, но вот не каждый компьютер правильно интерпретирует «корректную запись» в той или иной «системе кодирования» (мне понятнее, когда пишут – языке программирования) 4) По поводу MC#. А можно ли доверять (сейчас, да и в будущем) тому, что Вы пишите (в данном случае Вашему коду)? Я проделал огромную работу: 1) установил MC#, 2) скопировал Ваш код, 3) оттранслировал его. Замечу, что при этом я не добавил ни единого своего символа! Но трансляция не прошла!!! Неужели нужна еще какая-то отдельная переписка? Повторюсь, что версия ранее установленного языка MC# соответствует той, что и сейчас у Вас на сайте, другие задачи, взятые с Вашего же сайта идут нормально… Я с удовольствием Вам напишу, но … лучше по другому поводу. Ваш код просто обязан идти «в лет». И это Ваша проблема это обеспечить как для меня, так и для других… Я на это очень надеюсь и рассчитываю, т.к. мне очень хочется проверить на полную корректность Ваше решение на MC#. |
| 26.01.2009 13:05
YurySerdyuk | И, в третий раз, - протокол трансляции, пожалуйста ... |
| 02.02.2009 02:58
vlubch
| Что-то я так и не понял, как должна работать программа... См. мои комментарии по этому поводу в переписке по решению проблем работы со средой MC#. |
| 02.02.2009 10:15
vlubch
|
Спасибо за подправленный вариант. Но … давайте сравним протоколы работы программы с «бумажным анализом». Протоколы: Случай 1. Initial state: Y1 = 0 Y2 = 0 Case 1. x1 = 0, x3 = 0 X1=0, X3=0 --> Y1 = 1 Y2 = 1 Случай 2. Initial state: Y1 = 0 Y2 = 0 Case 2. x1 = 0, x3 = 1 X1=0, X3=1 --> Y1 = 1 Y2 = 0 Случай 3. Initial state: Y1 = 0 Y2 = 0 Case 3. x1 = 1, x3 = 0 X1=1, X3=0 --> Y1 = 0 Y2 = 1 Случай 4. Initial state: Y1 = 0 Y2 = 0 Case 4. x1 = 1, x3 = 1 X1=1, X3=1 --> Видно, что работа случаев 2 и 3 не соответствует «бумажным» случаям. Нет строчек со значениями Y1, Y2 равными 1. В случае 4 программа работает совсем необычно – не только не отображает значения Y1,Y2, но вообще … виснет! (?) Хотя следует заметить, что само завершение работы программы в случаях 1-3 вызывает вопрос. По идее, если не оговорено условие завершения работы процессов, они должны работать бесконечно или пока мы не снимем программу. |
| 03.02.2009 04:22
Dmitry Oganezov (Intel)
| У меня идея... А давайте может быть перенесем эту дискуссию в форум? Ну, или отдельный блог для нее сделаем? |
| 03.02.2009 05:14
yuryserdyuk
|
>Повторюсь, что версия ранее установленного языка MC# соответствует той, >что и сейчас у Вас на сайте, Во-первых, как выяснилось из присланного Вами протокола, Вы пользовались не той системой, что выставлена на сайте. Будьте, пожалуйста, внимательнее ... Во-вторых, сама программа, по аналогии с интерпретатором языка Unity, после запуска модели (RS-триггера) и подачи входных сигналов, обнаруживает стабильное состояние и только тогда выдает результат на печать. Т.е., промежуточные переходные состояния не отображаются. В частности, если стабильное состояние не наступает никогда (случай 4), то, программа, бесконечно переключаясь из состояния в состояние, не выдает результата вообще - "зависает" ... (Здесь можно модифицировать программу, например, можно после некоторого конечного числа циклов, например, тысячи, выдавать сообщение типа "Стабильное состояние не обнаружено"). Естественно,можно отображать все промежуточные результаты, но тогда, даже когда система входит в стабильное состояние, она будет обязана непрерывно генерировать один и тот же выход, выдавая километровые распечатки ... Такая реализация значительно упростит программу, поскольку в данном варианте основную трудность представляло обнаружение стабильного состояния системы, но с ней будет очень неудобно работать ... |
| 03.02.2009 23:15
vlubch
|
>У меня идея... А давайте может быть перенесем эту дискуссию в форум? Ну, или отдельный блог для нее сделаем? Идея хорошая. Мне так она нравится особенно :) Но пока есть несколько "но". Было бы, например, хорошо создать отдельный блог, назвав его хотя бы так: «Проблема RS-триггера, как … проблема параллельного программирования». Хотя, как показывает практика общения на эту тему, упоминание RS-триггера отвлекает от основной цели – обсуждения проблем параллельного программирования (не зря же Юрий задал вопрос по поводу операторов – не триггер ли это? :) ). И это большая проблема – люди никак не могут поверить в то, что все, что пишется о функционировании триггера, скажем мягко – полуправда. Но надо ли плодить темы, блоги… ? Проблема-то общая – понять что же такое параллельное программирование. А в форуме соответствующая тема «Теория параллельного программирования» в форуме уже есть. Начато в ней и обсуждение проблемы триггера. Но на нем пока там все и стало… В данном блоге собственно все и началось с описания решения триггера в форме двух параллельных операторов на том или ином языке программирования (пока обсуждаются языки Unity и MC#). О правильности его решения на Unity, не протестировав его, говорить рано. Сейчас мы обсуждает решение на MC#. Мы понемногу «подгоняем» решение под то, которое по идее должно получиться без всякой подгонки. Но дело даже не в «подгонке», а в том, что таким образом мы узнаем возможности MC#. И надо бы их понять до конца, чтобы решить достаточно ли нам для параллельного программирования MC# или … нужно переходить к анализу возможностей того же Unity. … Уж если заводить новую тему или блог, то, наверное, тогда, когда станут понятны ограничения того, что мы обсуждаем сейчас. Будет ли программист изучать другой язык, если ему достаточно возможностей того, которым он пользуется? Чтобы появился интерес – нужен повод. Сейчас повод изучать MC#, Unity и т.д. и т.п. их, как утверждается, высокоуровневость в сравнении с С++. Лично у меня на этот счет другое мнение. Но это пока лишь мое мнение – мнение отдельного специалиста. Его еще нужно обосновать. И здесь решение проблемы двух операторов - первый шаг, который может подтвердить или опровергнуть то, о чем я говорю. И вот если мы поставим хоть какую-то точку в нашем обсуждении понимания того насколько просто нынешнее программирование в рамках предлагаемых к обсуждению языков и библиотек мы поймем насколько нужна нам отельная тема или блог. Без этого все «повиснет» так, как сейчас повисло в форуме обсуждение теории параллельного программирования. Или в теории проблем уже нет? :) А они есть, т.к. нужно доказывать правильность того или иного решения не только «на бумажке», но и строго формально… Но не будем пока отвлекаться на теорию от проблем практики. Хотя, если честно, то надо начинать с теории, чтобы в практике было меньше проблем. Но уж такова правда жизни – пока не набьют шишек не думают о том, как их избежать заранее :). |
| 03.02.2009 23:40
yuryserdyuk
|
Вы ушли от главного вопроса - правильно ли реализует программа Model поставленную задачу? Если - да, то Вы должны дезавуировать свои слова про "умничанье" в этом блоге и про всё остальное - Вы там много чего понаобещали ... Надеюсь, что задача, которая не поддавалась решению 10 лет решена, и "кризис в многопоточном программировании" миновал :-) ? |
| 04.02.2009 04:10
vlubch
|
Теперь по поводу решения. Протокол работы говорит о том, что мы добились правильного решения. Но, вот именно, - добились! А это смущает и … нужны дальнейшие испытания на … параллелизм. Замечу, что далее мы не будем обсуждать сам язык (MC#), но только решения на его базе. 1. Сначала по поводу утверждения «добились». Это в простом случае мы может решить на бумажке, а потом сверить его с работой программы. А если бы мы не знали результата? Меня настораживает выражение «сама программа … обнаруживает». С чего это «она» вдруг решила, что меня интересует только «стабильное» состояние? :) Да, выполняя расчеты на калькуляторе, нас, скорее всего, не будут интересовать промежуточные состояния его работы. Но одно дело изолированный процесс (калькулятор), другое – параллельные процессы. Если они связаны между собой, то как раз именно промежуточными состояниями. Т.е. одно дело отдельный оператор y = not (x1 and x2) , и совсем другое – два таких же оператора, но связанными между собой теми же перекрестными связями. Именно связи между ними, по которым передаются «промежуточные переходные состояния», превращают систему из двух операторов в триггер (или осторожнее – похожую в некоторых режимах работы на триггер). Таким образом я не должен от параллельной программы ДОБИВАТЬСЯ правильного решения, которого я, как правило, не знаю (как заранее не знаю результат работы калькулятора). Но я должен доверять «параллельному калькулятору» будучи уверенным, что он покажет все результаты. В том числе и те, которые для кого-то промежуточные, а для меня, к примеру, имеющие значение (об этом далее). 2. Теперь о качестве решения на структурном уровне. Мы в исходной постановке имеем оператор у которого два входа – x1,x2 и один выход – y. Собственно так, или близко к этому, и должно быть. У нашего же метода AND_NOT аж семь параметров. Сравним вызов одного из методов AND_NOT с соответствующим ему оператором: Y1 = NOT ( x1 AND y2); md.AND_NOT ( 1, y1, y2, md.getX1, md.getY2, md.Y1, md.result1 ); Можно предположить, глядя на записи, что к оператору имеют отношения параметры 4-6 (счет параметров с 1). Используем это предположение, чтобы дополнить программу еще одним оператором, который позволит дать нам дополнительную уверенность в том, что мы можем получать решения ,которым можно доверять (подобно калькулятору). Но сначала о нашем предположении о роли остальных параметров (предположении, т.к. они не описаны разработчиком). 1-й – видимо, просто номер параллельного оператора; 2, 3 – выходной параметр и второй по порядку входной параметр (назначение этих параметров мне не понятно); 4,5,6 – как было сказано ранее – первый и второй входы и выход оператора; 7-й – параметр для метода print. Разработчики могут меня поправить, но я далее буду руководствоваться именно таким моим пониманием. 3. Если глянуть на код решения на MC# и в первую очередь на метод AND_NOT, то очевидна его сложность в сравнении с соответствующим ему оператором. Первое «лобовое решение» сократить число входных параметров до необходимого числа, а сервисную функциональность вынести за его пределы. Так, я бы с больше доверял методу вида (ср. с его описанием в п.2): md.AND_NOT (md.getX1, md.getY2, md.Y1); Т.е. Т.е., к примеру, все что связано с отображением состояния я вывел бы в отдельный оператор. Он как бы есть. Это print. И у него, вроде, есть доступ в пределах класса к переменной y1. Зачем нам еще что-то типа result? 4. Пусть соображения п.3 это наши фантазии из-за незнания языка MC#. Поэтому мы попробуем поступить так – добавим еще один вызов метода AND_NOT, рассматривая уже следующую систему параллельных операторов: y1 = NOT (x1 AND y2); y2 = NOT (x2 AND y1); y3 = NOT (y1 AND y2); С этой целью модифицируем код решения следующим образом: Добавим переменную y3. int y3 = 0; // Создадим еще один метод public handler getY3 int() & channel Y3 ( int x ) { return x; } Внесем изменения в код метода print public handler print void() & channel result1 ( int y1 ) & channel result2 ( int y2 ) & channel result3 ( int y3 ) { Console.WriteLine ( "Stable state = Y1 = " + y1 + " Y2 = " + y2 + " Y3 = " + y3 ); } Введем еще один параллельный процесс AND_NOT. Теперь это выглядит так: md.AND_NOT ( 1, y1, y2, md.getX1, md.getY2, md.Y1, md.result1 ); md.AND_NOT ( 2, y2, y1, md.getX2, md.getY1, md.Y2, md.result2 ); md.AND_NOT ( 3, y3, y2, md.getY1, md.getY2, md.Y3, md.result3 ); Результат – программа перестала работать. Может, я что-то сделал не так. Например, неверно интерпретировал параметры метода AND_NOT. Но если бы их было меньше, то меньше было бы и простора для моих фантазий :) … Общее впечатление от решения на MC# пока следующее. Решение есть и, кажется, добились того, чтобы его работа соответствовала предварительному анализу. Но … стоит его тронуть, как все рушится подобно … карточному домику. Да, несколько слов о том, что мы должны получить, введя еще один параллельный оператор. Можно и его вычислить «на бумажке». Пока это не так уж сложно. Но я бы хотел, чтобы «параллельный калькулятор» его вычислил сам. Пока же он завис. Можно, конечно, предположить, что я жму не на те «кнопки» или не так, но выше я постарался в них разобраться и свести риск к минимуму :) PS Выяснению того, что задача решена или ее решение подогнано, я и хочу разобраться, добавив еще один оператор. Давайте разберемся с ним. А уж потом и поговорим миновал или нет "кризис". Пока скажу так, что, благодаря решению на MC#, я верю, что к его решению мы приближаемся, но минуем ли - с этим еще предстоит разобраться :) Вопросы пока остаются ... :) |
| 04.02.2009 04:12
vlubch
| Кстати, Юрий, а к камим результатам должна привести работа еще одного оператора? |
| 08.02.2009 00:05
vlubch
|
Вернемся к «главному вопросу» - правильно ли реализует программа Model поставленную задачу? Правильно. Выполнены ли условия проверки MC# на параллелизм в рамках поставленной задачи? Нет. Поэтому более важный вопрос, чем решение конкретной задачи, – преодоления кризиса в параллельном программировании, не решен :) Таков пока итог наших разговоров. Чуть подробнее. Правильно – это еще не означает решение поставленной задачи. На структурном уровне каждый из приведенных операторов - это «черный ящик», имеющий два входа и один выход (можно сказать, что два входных канала и один выходной канал). Структурная модель задачи – это несколько подобных «ящиков», функционирующих параллельно, с заданными между ними связями. В исходной постановке – два «ящика», потом – три (последняя моя, так и не выполненная, просьба). Да. На функциональном уровне все эти ящики реализуют логическую функцию ИЛИ-НЕ (в общем случае это может быть произвольный алгоритм и произвольное число ящиков и связей между ними). Итак. В Model нарушено одно из базовых условий – модель оператора отличается на структурном уровне от реального оператора. А правильно решить поставленную задачу можно «одной левой» решить и в рамках чисто последовательной программы. Ситуация с данной задачи подобна ситуации с известным тестом Тьюринга «может ли машина мыслить?». Только там ведется диалог между человеком и неким «мыслящим объектом», находящимся в закрытой комнате, а в нашем случае тест должен свестись к работе человека в двумя комнатами, в которых находятся известные нам операторы, а между комнатами имеются определенные связи. Если человек не отличит, какие операторы находятся в данных комнатах (программные, физические или, к примеру, такие же операторы), то данный тест можно считать пройденным. В нашем случае, похоже, если мы оставим только заданное число входов/выходов, то … функционирование будет отличаться от того, которые ожидает увидеть наш оператор. Но все сказанное – пока лишь мое предположение, но, правда, основанное на вполне конкретных фактах. Их может развеять, наверное, лишь Юрий. Но он пока, к сожалению, молчит. Я могу, правда, сказать как должен работать дополнительный оператор. На его выходе во всех случаях, кроме единственного, будет значение единицы. В случае, когда на его входах две единицы, на выходе его будет ноль. Таким образом, данный оператор выполняет индикацию единичного состояния значений y1, y2. Если на его выходах всегда присутствует единица или пропускаются единичные состояния y1, y2, то или оператор сломался или система в целом функционирует неверно. |
| 12.02.2009 04:37
vlubch
|
Что-то множество вопросов «повисло»… :( Так и не было получено ответов на: 1. Можно ли на Unity записать код в естественном виде, т.е. в форме y1 = 1- ( x1 & y2 ) y2 = 1- ( x2 & y1 ) y3 = 1- ( у1 & y2 ) (здесь добавлен еще один оператор) 2. Как дополнить код на MC# третьим оператором? 3. Будет ли работать программа на MC#, если число параметров ограничить в соответствии с условием задачи? Юрий, есть проблемы? Иначе существует определенная нестыковка между тем, что утверждается и тем, что мы имеем реально. По крайней мере, в отношении MC#. По поводу Unity можно, конечно, доверять словам, но, как говорится, «лучше раз увидеть, чем сто раз услышать»… Пока же и не видно и не … слышно :( И, кстати, почему не слышно о том, можно ли получить на TBB решение поставленной задачи. Дмитрий как-то вскользь сказал, что не надо ожидать универсализма от нее. Вопрос к разработчикам - это так? Если так, то как и где узнать о границах применимости TBB? |
| 26.08.2009 22:20
vlubch
|
Продолжим? Хотелось бы свести число параметров в функции md.AND_NOT ( 1, y1, y2, md.getX1, md.getY2, md.Y1, md.result1 ); до фактически необходимого их числа - до трех (у элемента И-НЕ два входа и один выход). Возможно ли это? |

Alexey Kukanov (Intel)
14,316
Статусных баллов:
14,316
И Вас с Новым Годом!