Re[9]: Как можно обойти фон Неймана?
От: FR  
Дата: 28.03.06 06:05
Оценка:
Здравствуйте, Lazy Cjow Rhrr, Вы писали:


LCR>Кроме того, фиберы есть не на многих осях. Тогда в чём прикол фиберов? В том, что иногда кое-где их полезно ввернуть вместо потоков, дабы тормоза снять. Гапертон как-то рассказывал о таком случае — в его случае это было что доктор прописал. Универсален ли этот подход? Думаю, что нет.


Я не про фиберы конкретно(они были как пример), я именно про легкие (не OS и не аппаратные) потоки, например в том же питоне они без всяких фиберов реализуются, хотя по сути это тоже самое, реализация корпоративной многозадачности. Так вот такие потоки не паралелятся на многопроцессорных системах, поэтому в контексте данной темы мало полезны, а так в общем удобная и хорошая вещь.
Re[10]: Как можно обойти фон Неймана?
От: Lazy Cjow Rhrr Россия lj://_lcr_
Дата: 28.03.06 06:07
Оценка:
FR,

FR>Я не про фиберы конкретно(они были как пример), я именно про легкие (не OS и не аппаратные) потоки, например в том же питоне они без всяких фиберов реализуются, хотя по сути это тоже самое, реализация корпоративной многозадачности. Так вот такие потоки не паралелятся на многопроцессорных системах, поэтому в контексте данной темы мало полезны, а так в общем удобная и хорошая вещь.


В Эрланге параллелятся. Про GHC и GForth не могу сказать.
quicksort =: (($:@(<#[),(=#[),$:@(>#[)) ({~ ?@#)) ^: (1<#)
Re[7]: Как можно обойти фон Неймана?
От: AVC Россия  
Дата: 28.03.06 07:34
Оценка:
Здравствуйте, Lazy Cjow Rhrr, Вы писали:

LCR>Ну да, создание копии. И никаких проблем.

LCR>Проблемы с concurrency так или иначе решаются, но дело в том, что при некоторых консервативных предположениях, можно _существественно_ разгрузить накладные расходы на обеспечение параллелизма.
LCR>Пример такого предположения — отсутствие побочных эффектов. Позволяет, например, выкинуть локи, мьютексы и прочие семафоры, и облегчить threading model. Пример языков с лёгковесными потоками (процессами): Erlang, GHC Haskell, GForth.

Здесь у меня возник "технический" вопрос (скорее всего, наивный).
В функциональных языках "переменные" создаются и уничтожаются неявно. В частности, по этой причине необходим сборщик мусора (по крайней мере, так было раньше).
Как в ФЯ разруливается вопрос о доступе потоков к общим ресурсам (например, куче) без мьютексов или мониторов?
Есть общий ресурс (память), есть разные потоки, но нет синхронизации.
(Я догадываюсь, что мой вопрос наивный и чисто познавательный, так что это, конечно, не "критика".)
Обычный поток не требует специальных средств синхронизации до тех пор, пока он не обращается к разделяемым ресурсам.
Например, скромно вычисляет что-то в своем стеке с помощью реентерабельных функций без побочных эффектов.

LCR>На этой диаграммке всё видно, в частности отрыв "лёгкой" многопоточности от "тяжёлой".


LCR>
LCR>                       time     space  prog.size
LCR>1.0    Erlang HiPE #2  5.18     4,996    263    
LCR>1.1    Haskell GHC     5.86     2,696    236    
LCR>1.4    Forth GForth    7.00     1,052    305    
LCR>4.9    Smalltalk GST   25.32    8,676    435    
LCR>5.3    SML MLton #2    27.24    5,892    319    
LCR>5.6    Lua #2          29.00    1,664    229    
LCR>6.1    C++ g++         31.35    4,948    1086
LCR>...
LCR>

LCR>(В этом тесте запускается 500 потоков, что для Эрланга — просто детский лепет — для него и 50000 по зубам, если интересно могу привести рекорд).

Создается впечатление, что отрыв не так уж и велик.
Например Си побыстрее, чем Си++:

35 C gcc 181.46 3,876 519

А Ада еще быстрее:

13 Ada 95 GNAT 69.64 6,960 452

IMHO, заметно, что дело не только в императивности.

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


LCR>Да, конечно. Только таких функций будет очень и очень мало. Как только метод какого-нибудь класса обращается к своему полю с целью модификации — появляется побочный эффект, что существенно усложняет анализ.


Вот с этим и помогают бороться активные объекты.
Для потока активного объекта поле этого объекта также является "локальной переменной".
Ведь это поле принадлежит только активному объекту. Поэтому не требуются (за исключением особых случаев) средства синхронизации.

LCR>Ограничиться в императивных языках только модификацией локальных переменных попросту означает эмулировать функциональный стиль на таком языке. При отсутствии подходящей нотации, такая "эмуляция" обойдётся дорого как для программиста, так для процессора.


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

LCR>Насколько велика область задач, где нужен массивный параллелизм? Скорее мала, чем велика. Это одна из "стратосфер человеческой мысли", и туда с обычными молотками и гвоздями не суются. Там нужны более тонкие инструменты


Это, скорее всего, верно.

Но существует одно качество, которое нельзя купить, — это надежность. Цена надежности — погоня за крайней простотой. Это цена, которую очень богатому труднее всего заплатить.

Хоар
Re[7]: Как можно обойти фон Неймана?
От: FR  
Дата: 28.03.06 07:50
Оценка:
Здравствуйте, Lazy Cjow Rhrr, Вы писали:


LCR>На этой диаграммке всё видно, в частности отрыв "лёгкой" многопоточности от "тяжёлой".


Извиняюсь сразу ссылку не заметил, раньше я просто не доверял этому ресурсу, теперь же мое мнение о нем стало ниже плинтуса.
Уровень этих "тестов" c потоками такой же как и сравнение разных языков на разных алгоритмах(что у них уже было).
Re[2]: Никуда мы от от фон Неймана не денемся
От: Курилка Россия http://kirya.narod.ru/
Дата: 28.03.06 07:54
Оценка: +1
Здравствуйте, Геннадий Васильев, Вы писали:


ГВ>Ну он, вообще-то, не столько о компьютерах, сколько о том, что "you'll just have to find an approach that works for you personally" (найдите, мол, подход к обучению, который будет работать персонально для вас). Да и вообще — have a fun! Фон Нейманом он иллюстрирует влияние привычки на положение дел.

Про эту иллюстрацию и речь

ГВ>Притом рассуждает иной раз так, что мама, не горюй. Как архитектура Cell принципиально противоречит фон Нейману?

Если говорить строго — да, не противоречит (как ты вообще себе что-либо противоречащее фон Неймановской модели представляешь?), но это не машина фоннеймоновской модели, где есть процессор, память и операции выполняются строго последовательно
ГВ>Или в более общем смысле — машине Тьюринга? Там что, процессор процессором не является? Или память — это не память?
AFAIK, основное отличие от x86 — в явном прицеле на параллельные вычисления и развитые коммуникации.
(выделено мной)
Видимо ты не улавливаешь мысли, которую уже твердят давно и на RSDN в том числе, что стандартные языки (аля C и т.п.) не дают удобных концепций для описания свободно распараллеливаемых алгоритмов. Часто ФЯ упоминаются, но там далеко не всё так гладко как хотелось бы

ГВ>Так что, вопрос о языках для Cell, это вопрос о языках с поддержкой параллелизма, а никакой не contra-von Neuman. Кстати, "в лоб" параллелизм можно и на обычном C поддержать. Набор инструкций, это что? Правильно, это — процедура.

...
Много чего можно, можно и на ассемблере GUI-приложения писать и ещё много чего. Вопрос — насколько просто и удобно
Как раз на эту тему и мысль того поста — программисты ленивы, им лень изучать новые парадигмы, языки и т.п.
because they like to minimize the amount of crap they have to learn. Because learning is painful
Я лично имею привычку бороться с ленью, но это личный выбор каждого
Re[7]: Как можно обойти фон Неймана?
От: Сергей Губанов Россия http://sergey-gubanov.livejournal.com/
Дата: 28.03.06 07:57
Оценка: +2
Здравствуйте, Lazy Cjow Rhrr, Вы писали:

LCR>...Как только метод какого-нибудь класса обращается к своему полю с целью модификации — появляется побочный эффект...


Вот-вот именно отсюда и "растут ноги" активных объектов. Активный объект — это не просто сумма пассивного объекта и потока, а нечто большее — новая идеология, парадигма. Если ООП провозгласила, что все данные должны быть инкапсулированы в объектах, а поля объектов должны меняться только с помощью его методов, то парадигма активных объектов идёт дальше и говорит, что код методов зависящий от состояния объекта надо делать эксклюзивным (для данного объекта). В язык добавляется специальное служебное слово EXCLUSIVE ну, а дальше дело техники — компилятор сам разберётся...
Re[6]: Как можно обойти фон Неймана?
От: Дарней Россия  
Дата: 28.03.06 08:15
Оценка: +1
Здравствуйте, AVC, Вы писали:

AVC>Здесь, как мне кажется, и активные объекты как таковые не нужны.


А где они тогда вообще нужны?

AVC>Необязательно избегать использования переменных.

AVC>Достаточно, если это будут локальные переменные.
AVC>Если функция меняет только свои локальные (имеющие одно с ней время жизни и недоступные из других функций) переменные, то она не приводит к побочным эффектам. А разве не это главное?
AVC>IMHO, здесь важна локальность переменных, а не их полное отсутствие.

императивные циклы только усложняют работу компилятора.
А вообще у тебя уже получился гибридный язык, только ты сам не хочешь это признавать
... << RSDN@Home 1.1.4 stable rev. 510>>
Всех излечит, исцелит
добрый Ctrl+Alt+Delete
Re[8]: Как можно обойти фон Неймана?
От: AVC Россия  
Дата: 28.03.06 08:16
Оценка:
Здравствуйте, AVC, Вы писали:

AVC>Создается впечатление, что отрыв не так уж и велик.

AVC>Например Си побыстрее, чем Си++:
AVC>

AVC>35 C gcc 181.46 3,876 519

AVC>А Ада еще быстрее:
AVC>

AVC>13 Ada 95 GNAT 69.64 6,960 452

AVC>IMHO, заметно, что дело не только в императивности.

Здесь я ошибся: перепутал поля.
Оказывается, все наоборот, и Си++ быстрее, чем Си в 6 (!) раз.
Что, IMHO, уже кажется весьма странным.

Но существует одно качество, которое нельзя купить, — это надежность. Цена надежности — погоня за крайней простотой. Это цена, которую очень богатому труднее всего заплатить.

Хоар
Re[8]: Как можно обойти фон Неймана?
От: Lazy Cjow Rhrr Россия lj://_lcr_
Дата: 28.03.06 08:31
Оценка: +1
FR,

FR>Извиняюсь сразу ссылку не заметил, раньше я просто не доверял этому ресурсу, теперь же мое мнение о нем стало ниже плинтуса. Уровень этих "тестов" c потоками такой же как и сравнение разных языков на разных алгоритмах(что у них уже было).




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

Я придерживаюсь промежуточной точки зрения: эти тесты определённо не супер-мега-рулез, однако по их результатам можно более-менее судить о задачах, которые благоприятны для того или иного языка (вкупе с прочей информацией из других источников).
quicksort =: (($:@(<#[),(=#[),$:@(>#[)) ({~ ?@#)) ^: (1<#)
Re[7]: Как можно обойти фон Неймана?
От: AVC Россия  
Дата: 28.03.06 08:33
Оценка:
Здравствуйте, Дарней, Вы писали:

AVC>>Здесь, как мне кажется, и активные объекты как таковые не нужны.


Д>А где они тогда вообще нужны?


Там же, где нужны потоки, мониторы и т.п.

AVC>>Необязательно избегать использования переменных.

AVC>>Достаточно, если это будут локальные переменные.
AVC>>Если функция меняет только свои локальные (имеющие одно с ней время жизни и недоступные из других функций) переменные, то она не приводит к побочным эффектам. А разве не это главное?
AVC>>IMHO, здесь важна локальность переменных, а не их полное отсутствие.

Д>императивные циклы только усложняют работу компилятора.


Зато как облегчают работу программиста!
Защитим операторы присваивания от посягательств функциональщиков!! (лозунг )

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


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

Но существует одно качество, которое нельзя купить, — это надежность. Цена надежности — погоня за крайней простотой. Это цена, которую очень богатому труднее всего заплатить.

Хоар
Re[8]: Как можно обойти фон Неймана?
От: Курилка Россия http://kirya.narod.ru/
Дата: 28.03.06 08:39
Оценка:
Здравствуйте, AVC, Вы писали:

AVC>Но ведь главная идея функционального программирования — как раз в "чистоте".

Это ты откуда такое взял, расскажи?
AVC>Которой, как раз, что-то нигде не видно.
Haskell вроде как чистофункциональный, но большинство языков реализуют много парадигм.
Re[8]: Как можно обойти фон Неймана?
От: Дарней Россия  
Дата: 28.03.06 08:53
Оценка: 1 (1)
Здравствуйте, AVC, Вы писали:

AVC>Там же, где нужны потоки, мониторы и т.п.


это всё и без них прекрасно реализуется в любом из современных языков. Овчинка не стоит выделки.

AVC>Зато как облегчают работу программиста!


не вижу никакого особого облегчения

AVC>Даже нелюбимый тобой Вирт не отрицает влияния, которое ФЯ оказывают на императивные языки: рекурсия, исключение побочных эффектов и т.д.


не видел, где он про этого пишет

AVC>Но ведь главная идея функционального программирования — как раз в "чистоте".


с чего ты взял? Истина, как всегда, не в крайностях. Истина — она где-то посредине.
... << RSDN@Home 1.1.4 stable rev. 510>>
Всех излечит, исцелит
добрый Ctrl+Alt+Delete
Re[9]: Как можно обойти фон Неймана?
От: AVC Россия  
Дата: 28.03.06 08:55
Оценка:
Здравствуйте, Курилка, Вы писали:

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


AVC>>Но ведь главная идея функционального программирования — как раз в "чистоте".

К>Это ты откуда такое взял, расскажи?

Из книжки по функциональному программированию. (Кажется, Field и Harrison.)
Мол, главное — исключить программирование с помощью побочных эффектов (принцип "прозрачности по ссылкам").
Но если я неправильно это понимаю, буду благодарен за критику (можно даже с ругательствами, лишь бы по делу ).

Но существует одно качество, которое нельзя купить, — это надежность. Цена надежности — погоня за крайней простотой. Это цена, которую очень богатому труднее всего заплатить.

Хоар
Re[11]: Как можно обойти фон Неймана?
От: А почему вы спрашиваете Беларусь  
Дата: 28.03.06 09:01
Оценка:
Здравствуйте, Lazy Cjow Rhrr, Вы писали:

LCR>FR,


FR>>Я не про фиберы конкретно(они были как пример), я именно про легкие (не OS и не аппаратные) потоки, например в том же питоне они без всяких фиберов реализуются, хотя по сути это тоже самое, реализация корпоративной многозадачности. Так вот такие потоки не паралелятся на многопроцессорных системах, поэтому в контексте данной темы мало полезны, а так в общем удобная и хорошая вещь.


LCR>В Эрланге параллелятся. Про GHC и GForth не могу сказать.


В эрланге только в самом распоследнем снапшоте, который еще далеко не production ready и не скоро им станет.
Re[10]: Как можно обойти фон Неймана?
От: Дарней Россия  
Дата: 28.03.06 09:05
Оценка: +2
Здравствуйте, AVC, Вы писали:

AVC>Из книжки по функциональному программированию. (Кажется, Field и Harrison.)

AVC>Мол, главное — исключить программирование с помощью побочных эффектов (принцип "прозрачности по ссылкам").
AVC>Но если я неправильно это понимаю, буду благодарен за критику (можно даже с ругательствами, лишь бы по делу ).

некоторые задачи принципиально не решаются без побочных эффектов, что вполне очевидно. Но исключать побочные эффекты, где без них можно обойтись — дело конечно благое.
... << RSDN@Home 1.1.4 stable rev. 510>>
Всех излечит, исцелит
добрый Ctrl+Alt+Delete
Re[10]: Как можно обойти фон Неймана?
От: EXO Россия http://www.az.inural.ru
Дата: 28.03.06 09:06
Оценка: 6 (1) +1
Здравствуйте, AVC, Вы писали:
AVC> Мол, главное — исключить программирование с помощью побочных эффектов (принцип "прозрачности по ссылкам").

Это излишне экстремистский подход. Реально в практике используется много смешанных решений.
Например в Erlang есть такая штука, как "словарь процесса".
По сути — это те самые:
AVC> Активный объект — это поток + собственные локальные переменные объекта.
Что называется "один в один". То есть переменные "словаря процесса" меняются в Erlang так же как и в императивных языках. (Имнно меняются!) И этот словарь всегда локален для процесса, что здесь уже и предлагалось...
Другое дело, что используют его далеко не на каждом шагу — много других удобных абстакций.
Re[9]: Как можно обойти фон Неймана?
От: marat321  
Дата: 28.03.06 09:42
Оценка:
Здравствуйте, AVC, Вы писали:

AVC>Здесь я ошибся: перепутал поля.

AVC>Оказывается, все наоборот, и Си++ быстрее, чем Си в 6 (!) раз.
AVC>Что, IMHO, уже кажется весьма странным.

Видимо, libstdc++.so собирался с NPTL-версией glibc.

А программы на C компилялись с помощью LinuxThreads-версией glibc
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
silent
Re[9]: Как можно обойти фон Неймана?
От: FR  
Дата: 28.03.06 09:55
Оценка:
Здравствуйте, Lazy Cjow Rhrr, Вы писали:

LCR>FR,


FR>>Извиняюсь сразу ссылку не заметил, раньше я просто не доверял этому ресурсу, теперь же мое мнение о нем стало ниже плинтуса. Уровень этих "тестов" c потоками такой же как и сравнение разных языков на разных алгоритмах(что у них уже было).


LCR>


LCR>Критикуя, попробуй предложить другую методику (тем более, что в разных языках совершенно разные базовые абстракции, и я вообще не понимаю, как сделать "одинаковый алгоритм").


Угу сравнивать хеш с дервом очень "полезно".

LCR>Я придерживаюсь промежуточной точки зрения: эти тесты определённо не супер-мега-рулез, однако по их результатам можно более-менее судить о задачах, которые благоприятны для того или иного языка (вкупе с прочей информацией из других источников).


Нельзя по ним ни о чем судить, если этот тестировщик несколько лет ни может например настроить нормальный запуск питона с psyco из-за чего результаты тестов занижены на порядок, и если у меня на машине результаты сильно расходятся с ихними и если подправив пару строк получается намного быстрее, то все доверия нет.
Re[8]: Как можно обойти фон Неймана?
От: Lazy Cjow Rhrr Россия lj://_lcr_
Дата: 28.03.06 10:06
Оценка: 6 (1)
AVC,

AVC>Здесь у меня возник "технический" вопрос (скорее всего, наивный). В функциональных языках "переменные" создаются и уничтожаются неявно. В частности, по этой причине необходим сборщик мусора (по крайней мере, так было раньше). Как в ФЯ разруливается вопрос о доступе потоков к общим ресурсам (например, куче) без мьютексов или мониторов?


Синхронизация обеспечивается внутренними средствами RTS (вполне вероятно, что это могут быть системные мьютексы). Там для модифицируемых данных применяется реал-тайм менеджер памяти, а для обычных данных one-pass real-time mark-and-sweep:

Armstrong and Virding have proposed a one-pass mark-and-sweep garbage collector [AV95]. The collector is designed for languages that prohibit destructive operations (i.e. values can not be overwritten), and is used in a Erlang implementation. Since destructive operations are not allowed, references can only refer to older objects. The collector marks the objects from the youngest to the oldest. If no other object has referred to an object that is being marked, it can be reclaimed immediately (since only younger objects can refer to it.) All objects are kept in a singly linked list to keep the objects in order. All GC operations have predictable runtime
behavior. Thus, it can be used for real-time systems if it is scheduled to guarantee memory availability.

Опять же консервативные предположения и здесь позволяют неможечко подкрутить...

AVC>Обычный поток не требует специальных средств синхронизации до тех пор, пока он не обращается к разделяемым ресурсам. Например, скромно вычисляет что-то в своем стеке с помощью реентерабельных функций без побочных эффектов.

Просто чудесно. Мне только интересно, как это будет выглядеть.

1. При передаче объекта в функцию, мы должны копировать его, или
2. При передаче объекта в функцию, позволяется вызывать только немодифицирующие методы.

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

Возможно запутал, но вкратце будет так: чтобы смоделировать изменяющуюся сущность, мы отображаем эту сущность на язык (в виде объекта) и изменение этой сущности во времени моделируется с помощью изменения состояния объекта во времени. Есть альтернативный подход: изменение этой сущности во времени моделируется дискретной функцией (у которой значения меняются в зависимости от аргумента t, сама же функция является константной). Это подход ФЯ.

AVC>Для потока активного объекта поле этого объекта также является "локальной переменной".

AVC>Ведь это поле принадлежит только активному объекту. Поэтому не требуются (за исключением особых случаев) средства синхронизации.
Если один объект вызывает метод другого объекта и этот метод возвращает значение?
class A { public X meth(); }

class B
{
  private X x;
  public void fun(A a)
    {
        this.x = a.meth(); // здесь лок нужно захватить, а?
    }
}

Вопрос там, в комментарии...

AVC>А эмуляция императивного стиля на ФЯ?

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

AVC>А использование рекурсии там, где итеративное решение очевиднее и эффективнее?

Если рекурсия выглядит некрасиво, то я использую foreach(Fun, List) -> void().
Если этого мало, то я использую порт.
Правда, в случае побочных эффектов нужно смотреть в оба, чтобы они не вылезли за пределы функции, ну или процесса, если иначе никак. Обычная идеология скажем в Эрланге: каркас с побочными эффектами, наполнение — чистое.

AVC>И разве сложно эмулировать функциональный стиль на императивных языках?

AVC>Допустим, введем ключевое слово, означающее отсутствие у функции побочных эффектов.
AVC>Компилятор проверит это свойство и выдаст ошибку, если оно не выполняется.
AVC>Затем этот факт отсутствия побочных эффектов можно использовать при компиляции других функций.
Это неэффективно (и программиста напрягает, и вынуждает копировать объекты там, где бы компилятор ФЯ соптимизировал копирование).

State1 = modify(State), % ниже переменная State не используется

Выглядит, как будто копирование, а на самом деле модификация существующего объекта.

PS:
[AV95] Joe Armstrong and Robert Virding. One-pass real-time generational mark-sweep garbage collection.
quicksort =: (($:@(<#[),(=#[),$:@(>#[)) ({~ ?@#)) ^: (1<#)
Re[12]: Как можно обойти фон Неймана?
От: Lazy Cjow Rhrr Россия lj://_lcr_
Дата: 28.03.06 10:08
Оценка:
А почему вы спрашиваете,

LCR>>В Эрланге параллелятся. Про GHC и GForth не могу сказать.


АПВ>В эрланге только в самом распоследнем снапшоте, который еще далеко не production ready и не скоро им станет.


Ну ладно, _уже_ параллелятся.
quicksort =: (($:@(<#[),(=#[),$:@(>#[)) ({~ ?@#)) ^: (1<#)
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.