PD>И кстати, по твоей ссылке первая фраза
PD>On a multi-core processor, native thread implementations can assign work to multiple processors, whereas green thread implementations cannot.
В Хаскелле это не так. Там forkOS запускает поток OS, а forkIO — lightweight thread, причём
Just to clarify, forkOS is only necessary if you need to associate a Haskell thread with a particular OS thread. It is not necessary if you only need to make non-blocking foreign calls ... Neither is it necessary if you want to run threads in parallel on a multiprocessor: threads created with forkIO will be shared out amongst the running CPUs (using GHC, -threaded, and the +RTS -N runtime option).
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Это просто означает, что реального распараллеливания (то есть с квантованием времени и переключением в произвольный момент) там нет.
Почему? Переключать вполне может и VM. Да, это будет работать в пределах одного «тяжёловесного» потока, но, например, ожидание I/O можно таким образом распараллелить.
PD>Есть некое пседораспараллеливание, когда поток/процесс выполняет то одну часть кода, то другую. В любом случае OS может не дать этому потоку квант времени, и он будет спать и ждать, когда ему его дадут. И уж тем более здесь не удастся использовать те преимущества настоящей многопоточночти, как только речь пойдет об ожидании на объектах ядра. Стоит только начать ожидание — как блокируется поток Windows и все, ждите.
Не понятно, о что это за «преимущества». Вот например Erlang для массивной многопоточности (десятки и сотни тысяч процессов внутри VM) использует как раз что-то типа green threads. Процессы работают в рамках VM, и VM предоставляет им механизмы синхронизации (в случае Erlang это только посылка сообщения/приём). Т.е взять и заблокировать весь «тяжёлый» поток (предоставляемый OS) Erlang-овкий процесс не сможет.
Здравствуйте, AndrewVK, Вы писали:
AVK>Несерьезно, это не понимать, что читаемость кода и его близость к формулировке задачи — это самый важный параметр оценки качества этого самого кода.
и результаты его меня просто пугают. Но не хочу сейчас флейм на эту тему устраивать.
>Конечно, на таком игрушечном кусочке вроде как можно и пережить то, что ты продемонстрировал, но когда кусочки станут побольше, соотношение объема изапутанности сохранится, если не увеличится, и вот тут то это будет совсем уже не фигня.
А где там запутанность ? Нормальный код, как все на Win32 пишут.
AVK>Вот, кстати, характерная твоя ошибка — говорим о дизайне кода, а ты даже не в состоянии привести пример без использования специфики Win32.
Опять ? Я же привел тебе описание задачи! Ну не могу же я его привести, не упоминая окна и пикселей, если задача именно с окном и именно с пикселями.
>Все я прекрасно понимаю, но разбираться в этом принципиально не хочу, потому что к обсуждаемому вопросу это отношения не имеет.
Да никто и не заставляет. Ну не нравится тебе мое описание — сказал, я согласился, дал другое. Оно не нравится — скажи, уточню еще раз. Чего тему-то мусолить ?
AVK>Ты вообще понимаешь разницу между конструкциями языка и API операционной системы?
>Мы здесь, еще раз напоминаю, обсуждаем именно конструкции языка, и ничто иное. Обойтись без LINQ для демонстрации возможностей ФП на шарпе нельзя в принципе, обойтись без Win32 для демонстрации того, что LINQ ничего не дает можно, и даже нужно.
Согласен. Я вполне могу убрать оттуда и окно, и GetPixel, а просто предложить просуммировать столбцы некоего двумерного массива, каким-то образом заданного. Правда, чтобы время померить, придется либо в цикл это вставить, либо уж очень большой массив использовать. Впрочем, чтобы IT-ские проценты сравнить в AsParallel и без, то же придется сделать. Но все же никак не пойму — чего ты к пустякам придираешься ? Ну какое отношение к распараллеливанию имеет вопрос откуда и как брать эту матрицу ?
AVK>Конечно, в том и суть, что ты, ничего не зная ни про ФП, ни про LINQ, тем не менее понимаешь код, который IT привел.
Вообще-то нет. Про ФП я могу не знать, про LinQ тоже, а вот SQL знать надо, иначе я его этот SELECT и GROUP в нем не пойму.
AVK>>>А теперь сравни со своей простыней. Что там у нас осталось? Параллелить вкривь и вкось различными способами?
PD>>Если не сложно, объясни , почему вкривь и вкось, это раз
AVK>Не знаю, тебе захотелось по диагонали или еще как то там пиксели обсчитывать.
Андрей, это уж никуда не годится. Я привел этот пример именно, чтобы показать, что когда мне надо не в "горизонтально-вертикальном", а в произвольном направлении ходить, ваш подход ИМХО пробуксовывает. ИМХО, заметь — я же вопрос задал, а не утверждал, что нельзя. Если докажешь, что можно и логично при этом получится — признаю, конечно. Ну а насчет того, что , мол, вкривь и вкось — не будешь же ты утверждать всерьез, что матрицы только по строкам или по столбцам проходят
Я вот одно понять не могу. Ну что стоит признать, что для определенной ситуации этот подход не очень хорош ? Вот был бы я на вашем месте, ответил бы так — "да, для такого рода действий этот подход не годится или не очень эффективен (или еще что-то). Зато он очень хорош, для задач типа той, о которйк я написал". И все, вопрос исчерпан, и я тут же соглашусь — для заточки карандашей не годится топор, а дерево рубить не надо столовым ножиком. И обсуждать больше нечего, разве что детали и эффективность того или иного решения.
AVK>Понимаю. И что? Я тебе в который раз напоминаю — речь не о библиотеках и их возможностях, речь о языке программирования. AsParallel просто демонстрирует эти возможности, не более того.
Понимаешь, для меня большой разницы между языком и библиотекой нет. Реально для меня это два взаимосвязанных инструмента, и без одного из них, любого, я не обойдусь. Теоретически обойдусь, пока просто так думаю, а как сяду за компьютер — нет. Как ни страшно это для тебя звучит, но это так. Ну хорошо, давай оставим только язык. Linq твой останется, допустим, но ведь всех библиотек .NET FW я тебя лишу, если ты хочешь меня лишить Win32. И что ты сможешь сделать ? Или ты заявишь, что .Net FW — это часть языка, а Win32 — нет ? Массивы в C# — это часть языка или нет ? Безусловно да, входят в спецификацию. Но ведь без реализации класса Array в .Net FW не будет у тебя массивов!
PD>> Не обязательно так, конечно, скорее там пул потоков, посмотрю как-нибудь. Ну нет в Win32 иного способа параллелить и нет в Windows ничего, что не проходио бы через Win32 (про OS/2 и POSIX умолчим).
AVK>Оторвись от замочной скважины и открой наконец дверь.
Да пойми ты наконец, что все проходит через эту замочную скажину, если уж тебе такое сравнение нужно. Я абсолютно ниченго не знаю, скажем, про реализации ЛИСПА, да и сам ЛИСП не знаю, но если мне кто-то скажет, что в ЛИСПЕ можно записать файл, минуя в конечном счете WriteFile — это даже не смешно.
PD>>Итераторы в С++ существуют, а вообще это понятие языково-независимо.
AVK>Под итераторами в C# здесь подразумеваются специальные возможности языка. Это частный случай продолжений (continuations), предназначенный для легкого и удобного создания сложных итераторов. В С++ такое эмулируют при помощи макросов, но качество решения получается при этом ниже плинтуса.
Ну это обсуждать не будем, предлагаю так, а то мы еще один флейм устроим.
PD>> Вот ответь прямо — да или нет ?
AVK>Отвечаю прямо — неважно.
Не ответил
>Не уводи от темы. Распараллеливание здесь в качестве примера, а не самоцель.
А вот в этом не уверен. IT именно это и заявил — могу , мол, легко распараллелить.
>Если не можешь съехать с Win32, я могу в примере заменить распараллеливание на, скажем, кеширование.
Ты хочешь, чтобы мы еще флейм на тему кеширования завели ? Не надо
PD>>Честно говоря, не слишком понял — что ты суммируешь и куда. Если это реализация моей задачи
AVK>Она.
PD>> — где массив сумм по столбцам ?
AVK>Вот тебе с массивом, это еще проще: AVK>
AVK>return
AVK> (
AVK> from x in Enumerable.Range(0, Width)
AVK> select Enumerable.Range(0, Height).Sum(y => pixels[x, y])
AVK> )
AVK> .AsParallel()
AVK> .ToArray();
AVK>
AVK>Обрати внимание, насколько просто оказывается поменять код.
Да просто, кто спорит. Я еще раз говорю — я совсем не противник этого. Я не согласен, когда это за панацею выдается.
А все же, как с диагоналями ? . Мне-то несложно. PD>>Ты все же попробуй те 5 вопросов осилить.
AVK>Смысл? Игрища с приоритетами потоков в контексте вопроса малоинтересны и непринципиальны (ну будет там какой нибудь доп.параметр у AsParallel()).
Вот то-то и оно. IT уверен — напишу AsParallel и все, остается только сливки снимать. Ты уже засомневался, и это верно, хочешь какой-то параметр (в скобках — или метод, или аттрибут или еще что-то). Дело в том, что поручив все это системе(библиотеке, FW) и надеясь, что она сделает все наилучшим образом, ты очень скоро поймешь, что иногда да, это совсем неплохо, а иногда — ни в какие ворота. И тогда тебе придется изучать всю эту кухню (не обязательно на Win32, реализация Thread в С# в общем, повторяет Win32) и требовать, чтобы у AsParralel были какие-то возможности управления.
Хотя теоретически да, можно представить себе систему, которая сама примет решение о том, как и когда распараллеливать алгоритм. Но эта задача эквивалентна задаче автоматического распараллеливания произвольного алгоритма, а ее, насколько я понимаю, еще никто не решил. Впрочем, почитай здесь же в форуме, ИМХО с год назад тут большая дискуссия была о параллелизме.
PD>> А это суммирование, конечно, распараллелить можно, задачка-то пустяковая.
AVK>Только даже на такой пустяковой задачке прекрасно видно, насколько твой императивнй код запутаннее.
Андрей, не надо. Код как код, делает то, что ему положено, и запутанного там ничего нет. Ты просто мой код еще не знаешь — если уж я впрямь начну запутанный код писать, его никто, кроме меня, не распутает (Ох, какой козырь я тебе дал — но будь джентльменом, не воспользуйся им, прошу
PD>>Вообще-то я не очень понимаю — в чем разница. Он какие-то проценты считает на баз неких коллекций, а я суммы считаю на базе тоже, если хочешь, "коллекций — столбцов пикселей.
AVK>У него алгоритм намного сложнее, а, главное, там уровень косвенности выше.
У него в реальных его задачах — не сомневаюсь. И никаких сомнений в его качествах как специалиста я не высказывал, это ему очень хочется доказать, что я проценты считать не умею. Алгоритм вычисления процентов — мб и сложнее, чем вычисления сумм, но, по правде сказать, обоим (как алгоритмам) место в средней школе во втором-третьем месяце изучения программирования.
PD>> Делить я не делю и не суммирую, верно, но так ли это важно ? Есть распараллеливание алгоритма, что тут особого-то.
AVK>Ты сделай сперва без распараллеливания, и мы обсудим результат.
LCR>Вот, по-моему это и есть ключевая фраза. Все задачи не переберёшь, следовательно экстенсивный путь уже обречён на неудачу. Мы можем реализовать сложение, умножение, инвертирование матриц, матрицы могут быть ленточные, треугольные, разряжённые, но этого всё-равно ничтожно мало, за бортом по-прежнему множество алгоритмов счётной мощности, куда уже не сунешься, потому что выразительных средств недостаточно.
Если использовать крупноблочное строительство, то всегда найдется проект, для которого ни один набор выпускаемых крупных блоков не подходит. Если строить из кирпичей, то можно построить все, что угодно — от утепленной собачьей будки до собора святого Петра.
LCR>На данный момент необходимо иметь такой базовый набор выразительных средств (нотацию, язык — назовите как угодно), которая LCR>1. Позволяет реализовать любой алгоритм в принципе
Из кирпичей можно все построить.
LCR>2. Позволяет реализовать любой алгоритм практически, причём реализация была или как можно более эффективной (учитывала конкретное окружени
е включая кэши, конвейеры, наличие нескольких ядер), или давала гарантии по эффективности или затратам памяти.
И будет это здание наиболее эффективным. Некоторые их них уже 2000 лет стоят. И все там учитывают , если надо — от сейсмостойкости до розы ветров.
LCR>Несложный анализ показывает, что вышеназванная Альфа никак укладывается в требования выше.
Коля, вы что говорите! Эта Альфа 1968 г.р.
>Чтобы попытаться накрыть ладонью всё множество алгоритмов, выделения кусочка кода и возможность обозвать его "+" явно недостаточно. Нужна модульность, много модульности, больше чем сейчас. Поясню на примере.
LCR>Допустим, вы реализовали умножение матриц, причём учли и кэши, и многопроцессорность, и учли специфику Intel/AMD и ещё много чего. То есть, ваш алгоритм стал очень очень быстрым, так что на любой машине это оказалась самая эффективная реализация.
LCR>Я делаю преобразование Лапласа, (или решаю нелинейные уравнения, или делаю какой-нибудь комбинаторный алгоритм), и теперь мне тоже надо его сделать как можно быстрее. Я запрограммировал его в виде функции laplas_transform, и теперь как мне выделить из вашего алгоритма отражение знания об архитектуре и использовать с моей функцией? Как вообще сделать так, чтобы это было возможно?
А так же, как делали умножение. С учетом кэшей, и многопроцессорности, и специфики Intel/AMD и ещё много чего. Наверняка многие решения совпадут, но, в общем, это разные алгоритмы, и оптимизировать их надо по -разному.
LCR>А Вася, например, хочет взять ваш алгоритм, и сделать так, чтобы вместо вещественных чисел можно было использовать символьные значения (ему нужны символьные алгебраические преобразования).
Что-то я не понял. Вы собрались матрицы в символьном виде перемножать ? Задача достойная, но это не арифметика, а обработка текста в основном. И оптимизация совсем другого, мб, понадобится — рабботы со строками, к примеру.
LCR>А Таня, вдобавок, хочет взять ваш алгорить, и сделать так, чтобы вместо вещественных чисел были функции, да ещё и на комплексном пространстве.
LCR>И, наконец, Алиса, взяв ваш алгоритм в качестве процедуры, вдруг осознала, что он и является главным пожирателем процессорного времени, но специфика задачи позволяет вычислять всё произведение не сразу, а по немножку. И её осенило, что если в вашем алгоритме использовать ленивые for-ы, то всё становится замечательно.
Что-то много у вас знакомых, и все они чего-то хотят
LCR>Единственный разумный путь сделать счастливыми всех четырёх человек, как мне видится, это декларативно описать алгоритм и возложить знание об архитектуре и окружение на компилятор (так что компилятор и будет модулем optimize, можно считать что каждая функция описана как f = optimize f_). Такое декларативное описание присутствует в коде на Хаскеле, и в подавляющем большинстве случаев отсутствует в коде на C++, так что бедные Вася, Таня, Алиса и ваш покорный ученик должны заново изобретать свои многоугольные колёса.
К сожалению, если поручить это все оптимизатору компилятора, то этот компилятор должен будет быть попросту гениальным, то есть включать в себя знание всех и всяческих техник, трюков и т.п, связанных и с кэшами, и с многопроцессорностью и с характером задачи. Увы, это вряд ли реально. Компилятор будет в лучшем случае оптимизировать "в среднем", то есть в расчете на некую среднюю задачу. И чем выше уровень абстракций, тем хуже он это будет делать. Оптимизировать цикл можно очень хорошо, а оптимизировать задачу "сделай вот это" — можно лишь на бвзе некоторых правил оптимизации общего порядка. Как только попадется нечто, что под эти правила не подходят — результат будет плохим.
Оптимизировать задачу "построите мне автоматически жилой дом" — можно. Выбираем подходящие блоки, стыкуем их, определяем , в каком порядке их ставить, ставим, замазываем щели — дом готов.
Оптимизировать задачу "постройте мне автоматически собор святого Петра" — нельзя. Для этого Браманте и Микеланджело нужны. А если эту задачу оптимизировать автоматически, то в итоге получится утепленная собачья будка размером с собор святого Петра.
Здравствуйте, gandjustas, Вы писали:
G>Это называет распараллеливанием ожидания. Все нормальные люди тут говорят про распараллеливание вычислений.
G>Достаточно вместо GetPixel взять массив точек в памяти (выдрать с помощью GetDIBits). Потом можно сравнить результаты.
Да, конечно. Я просто хотел подчеркнуть, что распараллеливание — совсем не такое простое действие. Иногда и на одном процессоре можно, иногда — не имеет смысла. Иногда и то и другое
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Если использовать крупноблочное строительство, то всегда найдется проект, для которого ни один набор выпускаемых крупных блоков не подходит. Если строить из кирпичей, то можно построить все, что угодно — от утепленной собачьей будки до собора святого Петра.
Отличный пример.
Расходы на строительство оказались столь велики, что для покрытия их папе Льву X пришлось за большую сумму денег передать право распространять индульгенции Альбрехту Брандербургскому. Злоупотребления индульгенциями в немецких землях вызвали протест Лютера, Реформацию и последующий раскол Европы.
PD>Из кирпичей можно все построить.
Ну да, попробуйте что-то вроде Salginatobel Bridge из кирпичей построить. Из кирпича не построить даже Flatiron Building, здания из кирпича имеют тенденцию расползаться под собственной тяжестью.
... << RSDN@Home 1.2.0 alpha 4 rev. 1110>>
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Здравствуйте, gandjustas, Вы писали:
G>>Это называет распараллеливанием ожидания. Все нормальные люди тут говорят про распараллеливание вычислений.
G>>Достаточно вместо GetPixel взять массив точек в памяти (выдрать с помощью GetDIBits). Потом можно сравнить результаты.
PD>Да, конечно. Я просто хотел подчеркнуть, что распараллеливание — совсем не такое простое действие.
Это смотря как писать.
PD>Иногда и на одном процессоре можно, иногда — не имеет смысла. Иногда и то и другое
Еще раз: распараллеливание вычислений на одном процессоре только уменьшит быстродействие.
Распараллеливание ожидания лучше выполнять не с помощью ручного создания потоков.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>К сожалению, если поручить это все оптимизатору компилятора, то этот компилятор должен будет быть попросту гениальным, то есть включать в себя знание всех и всяческих техник, трюков и т.п, связанных и с кэшами, и с многопроцессорностью и с характером задачи. Увы, это вряд ли реально.
Но теоретически возможно. Что и требовалось доказать.
PD>Компилятор будет в лучшем случае оптимизировать "в среднем", то есть в расчете на некую среднюю задачу. И чем выше уровень абстракций, тем хуже он это будет делать. Оптимизировать цикл можно очень хорошо, а оптимизировать задачу "сделай вот это" — можно лишь на бвзе некоторых правил оптимизации общего порядка. Как только попадется нечто, что под эти правила не подходят — результат будет плохим.
Можно не писать то, что под эти правила не подходит. Или язык будет запрещать так писать.
PD>Оптимизировать задачу "построите мне автоматически жилой дом" — можно. Выбираем подходящие блоки, стыкуем их, определяем , в каком порядке их ставить, ставим, замазываем щели — дом готов. PD>Оптимизировать задачу "постройте мне автоматически собор святого Петра" — нельзя. Для этого Браманте и Микеланджело нужны. А если эту задачу оптимизировать автоматически, то в итоге получится утепленная собачья будка размером с собор святого Петра.
Метафора строительства зданий далеко не всегда адекватна для программирования.
В случае декларативного описания решения алгоритмической задачи такая метаформа совсем неадекватна.
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, Pavel Dvorkin, Вы писали: S>>>То есть тебе не очевидно, что твоя программа "с параллельностью", запущенная на одном ядре, будет менее эффективной, чем твоя же программа "без параллельности"? PD>>Не только не очевидно, но в общем случае и неверно. S>Павел, хватит придуриваться.
Антон, хватит употреблять непарламентские выражения. Ты иначе не умеешь ?
S>Павел, ты же такой крутой специалист. Что тебе непонятно? Что программа №1 делает всё в одном потоке — в том, в котором вызвали? S>Или что программа номер 2 при вызове на 1 ядре занимается ерундой — выделяет память, создает объекты синхронизации, передает управление во второй поток и тупо садится ждать его выполнения?
Ах вот ты о чем! Извини, действительно не понял. Да, тут ты прав — код #2 потребует дополнительных расходов, верно. Но код #1 был просто приведен для сравнения скорости. Употреблять его вообще нельзя — он замораживает интерфейс. Это надо в поток выносить в любом случае.
S>Павел, я с ними знаком.
Не верится. Иначе не стал бы ты такое заявлять.
S>>>Если первое — то непонятно, зачем тебе разжевывать, куда деваются такты и байты памяти при лишних вызовах WaitForMultipleObjects и new[].
PD>>О господи! Это уж за всякие пределы выходит. Придется ликбез провести.
PD>>WaitForMultipleObjects практически никаких тактов вообще не требует в user mode. Все, что делается при ее вызове — засылка параметров в стек и int 2eh. Все. Поток больше делать ничего не может, так как спит сном праведника и сам себя разбудить не может. Просто в ядре Windows он теперь добавлен в список тех потоков, которые на этом ивенте/мютексе... ждут. Он спит. И когда мютекс сей освободится — ядро проверит его (потока) приоритет, и если он выше приоритета текущего потока, даст ему управление, а если нет — в очередь готовых потоков. Так что WaitFor... работает почти целиком в kernel-mode. А в этом kernel mode этот поток — лишь один из многих, котррыми система управляет. Это все называется накладные расходы, если их не хочешь — возвращайся в DOS. И вопрос в том, перекрывает ли ожидаемый выигрыш от распараллеливания эти расходы или нет. S> Я фигею.
Похоже, это твое основное состояние. Если ты фигееешь от того, что во всех руководствах написано (Еще раз — почтай Рихтера), и что я просто пересказал своими словами, не добавив от себя ничего — ну что же...
S>А теперь ты вдруг вспомнил про "практические соображения". Если мы перейдем к ним, то нам неизбежно придется вспомнить о том, что идеальных программистов и бесконечного времени на ручную оптимизацию не бывает.
А кто спорит ? Я же тысячу раз говорил — вопрос об идеальной программе есть теорема существования. А в реальности надо выбор делать. Если времени разработчика мало, а сроки поджимают, а производительность некритична — делай хоть на Linq, хоть на GW-Basic . Если наоборот — пиши на C++ или даже на ассемблере (отдельные куски).
S>По поводу мультипрограммирования тебе тут уже отвечали: речь не о распараллеливании ожидания. Хотя, конечно, опытным оптимизаторам известно, что даже для него применять потоки ядра — роскошь, а не средство передвижения.
Почитай Рихтера, особенно 2-й том. APC пользовательского режиа, порты ожидания, особенно им рекомендуемые, асинхронный ввод-вывод, процедуры завершения. Тогда не будешь такое говорить.
>Если бы ты дал себе труд ознакомиться с архитектурой высокопроизводительных приложений, то убедился бы, что никто не выделяет "1 поток — 1 задача".
Нет такого понятия в Windows — задача. Исключено при переходе Win16->Win32. Если речь идет о процессе, то он здесь ни при чем, так как Windows занимается квантованием времени на уровне потоков, а не процессов. Так что уж, будь добр, определи, что означает слово "задача" в твоем понимании, а тогда и обсудим, сколько потоков должно быть на задачу или задач на поток. Только все же сначала почитай Рихтера. Там эта архитектура подробно рассматривается.
>Для распараллеливания ожидания эффективнее кооперативная многозадачность и программный параллелизм.
Привет от Windows 3.11
Ожидания чего ? Ответа/запроса пользователя в каком-нибудь www-сервере ? Ожидание завершения операции ввода/вывода на диске ? Ожидание по таймеру ? И т.д. Это все совершенно разные действия, и методы тут разные. Где-то режим опроса (поллинга) эффективнее, где-то он совсем не годится. Представляю себе поллинг в ядре Windows
S>Причем опять же, пространство решений для неё слишком велико, чтобы покрыть его "оптимизированным кодом, написанным на ассемблере". Читать про свитч AXD-301.
Вот уж это читать не буду. У меня других дел хватает, чтобы еще свитчами заниматься.
Здравствуйте, Klapaucius, Вы писали:
K>Здравствуйте, Pavel Dvorkin, Вы писали:
PD>>Если использовать крупноблочное строительство, то всегда найдется проект, для которого ни один набор выпускаемых крупных блоков не подходит. Если строить из кирпичей, то можно построить все, что угодно — от утепленной собачьей будки до собора святого Петра.
K>Отличный пример. K>
K>Расходы на строительство оказались столь велики, что для покрытия их папе Льву X пришлось за большую сумму денег передать право распространять индульгенции Альбрехту Брандербургскому. Злоупотребления индульгенциями в немецких землях вызвали протест Лютера, Реформацию и последующий раскол Европы.
Верно!
Но построили же! Другого такого нет!
PD>>Из кирпичей можно все построить.
K>Ну да, попробуйте что-то вроде Salginatobel Bridge из кирпичей построить. Из кирпича не построить даже Flatiron Building, здания из кирпича имеют тенденцию расползаться под собственной тяжестью.
Здравствуйте, gandjustas, Вы писали:
G>Здравствуйте, Pavel Dvorkin, Вы писали:
PD>>К сожалению, если поручить это все оптимизатору компилятора, то этот компилятор должен будет быть попросту гениальным, то есть включать в себя знание всех и всяческих техник, трюков и т.п, связанных и с кэшами, и с многопроцессорностью и с характером задачи. Увы, это вряд ли реально. G>Но теоретически возможно. Что и требовалось доказать.
Я пытаюсь эту ситуацию сейчас понять. В общем, видимо, с идеальной программой я не совсем прав. При бесконечном количестве ресурсов ее не может быть. При ограниченном количестве она все же существует. Додумать надо.
PD>>Компилятор будет в лучшем случае оптимизировать "в среднем", то есть в расчете на некую среднюю задачу. И чем выше уровень абстракций, тем хуже он это будет делать. Оптимизировать цикл можно очень хорошо, а оптимизировать задачу "сделай вот это" — можно лишь на бвзе некоторых правил оптимизации общего порядка. Как только попадется нечто, что под эти правила не подходят — результат будет плохим. G>Можно не писать то, что под эти правила не подходит.
Так я об этом и говорю. Каждому инструменту — свое назначение. Где Linq, где ассемблер. кесарю кесарево, слесарю — слесарево
PD>А кто спорит ? Я же тысячу раз говорил — вопрос об идеальной программе есть теорема существования.
Подробное опровержение т.н. "теоремы существования" см. здесь
.
S>>По поводу мультипрограммирования тебе тут уже отвечали: речь не о распараллеливании ожидания. Хотя, конечно, опытным оптимизаторам известно, что даже для него применять потоки ядра — роскошь, а не средство передвижения.
PD>Почитай Рихтера, особенно 2-й том. APC пользовательского режиа, порты ожидания, особенно им рекомендуемые, асинхронный ввод-вывод, процедуры завершения. Тогда не будешь такое говорить.
Я продолжаю поражаться способностью некоторых людей смотреть в книгу, а видеть известную фигуру из трех пальцев. В том плане, что Рихтер как раз описывает способ минимизировать количество ядерных потоков для реализации асинхронных задач. Простой вопрос на понимание сути: для чего все эти припрыгивания с процедурами завершения, если можно тупо сделать блокирующий вызов в своем потоке?
>>Если бы ты дал себе труд ознакомиться с архитектурой высокопроизводительных приложений, то убедился бы, что никто не выделяет "1 поток — 1 задача".
PD>Нет такого понятия в Windows — задача. Исключено при переходе Win16->Win32. Если речь идет о процессе, то он здесь ни при чем, так как Windows занимается квантованием времени на уровне потоков, а не процессов. Так что уж, будь добр, определи, что означает слово "задача" в твоем понимании, а тогда и обсудим, сколько потоков должно быть на задачу или задач на поток. Только все же сначала почитай Рихтера. Там эта архитектура подробно рассматривается.
Задача здесь подразумевается пользовательская. К примеру, "прочитать 8192 байта с диска". Или, более крупно, скажем "обработать входящий http-запрос".
Очевидное решение — выделить каждое соединение в отдельный поток, чтобы обеспечить максимальный параллелизм. Вот только так никто не делает: слишком велики накладные расходы на управление сотнями потоков, так как они большую часть времени спят. Делают пул в пару десятков потоков на ядро, и его с запасом хватает для всех этих операций. Почитай Рихтера, там это хорошо описано
>>Для распараллеливания ожидания эффективнее кооперативная многозадачность и программный параллелизм. PD>Привет от Windows 3.11
Нет. Привет от файберов, lighttpd и SQL Server. Не стесняйся, Павел, учи матчасть.
PD>Ожидания чего ? Ответа/запроса пользователя в каком-нибудь www-сервере ? Ожидание завершения операции ввода/вывода на диске ? Ожидание по таймеру ? И т.д. Это все совершенно разные действия, и методы тут разные.
Это, Павел, от того, что твои знания — совершенно бессистемные. Ты не понимаешь, что JIT по отношению к x86 делает c MSIL то же самое, что Pentium делает с x86 кодом по отношению к своему микрокоду. Не понимаешь, что ожидание в www-сервере, файлового ввода-вывода, и таймера устроены совершенно одинаково. И методы везде применяются те же самые.
PD>Где-то режим опроса (поллинга) эффективнее, где-то он совсем не годится. Представляю себе поллинг в ядре Windows
Давненько я не видел задач, где поллинг был бы хоть как-то приемлем.
S>>Причем опять же, пространство решений для неё слишком велико, чтобы покрыть его "оптимизированным кодом, написанным на ассемблере". Читать про свитч AXD-301. PD>Вот уж это читать не буду. У меня других дел хватает, чтобы еще свитчами заниматься. Да здравствует упорствующее невежество.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Andrei F., Вы писали:
AF>Побочные эффекты в виде вывода на экран — это цель создания GUI.
На основании чего ты решил, что вывод на экран это побочный эффект?
AF>А когда этот оппонент доказывает мне одно, а в соседней ветке проталкивает прямо противоположное — вот тогда сомнения уже закрадываются...
Цитаты, конечно, будут?
... << RSDN@Home 1.2.0 alpha 4 rev. 1111 on Windows Vista 6.0.6001.65536>>
welcome to real world
PD>А где там запутанность ? Нормальный код, как все на Win32 пишут.
Самому не смешно?
AVK>>Вот, кстати, характерная твоя ошибка — говорим о дизайне кода, а ты даже не в состоянии привести пример без использования специфики Win32.
PD>Опять ? Я же привел тебе описание задачи!
Тогда забудь в этом топике про слово Win32, ты же его через абзац упоминаешь.
PD> Ну не могу же я его привести, не упоминая окна и пикселей, если задача именно с окном и именно с пикселями.
Вот об этом и речь.
PD>Да никто и не заставляет. Ну не нравится тебе мое описание — сказал, я согласился, дал другое.
Нук а я тебе дал ответ. Что тебя еще не устраивает?
PD> Впрочем, чтобы IT-ские проценты сравнить в AsParallel и без, то же придется сделать. Но все же никак не пойму — чего ты к пустякам придираешься ? Ну какое отношение к распараллеливанию имеет вопрос откуда и как брать эту матрицу ?
Никакого. Только ты погляди на свои аргументы:
Если бы я это в форуме по Win32 написал ...
Если ты не очень понимаешь Win32 ...
Ну нет в Win32 иного способа параллелить и нет в Windows ничего, что не проходио бы через Win32
Распараллеливание тоже (не в С++, а в Win32)
И никак нельзя распараллелить иначе, чем Win32 ...
Win32, Win32, Win32, Win32. Напоминаю — обсуждать тут пытались конструкции языков программирования. Я понимаю, тебе про этот Win32 каждый день приходится студентам рассказывать, но надо хоть чуть чуть абстрагироваться, если тема разговора никакого отношения к Win32 не имеет.
PD>Вообще-то нет. Про ФП я могу не знать, про LinQ тоже, а вот SQL знать надо, иначе я его этот SELECT и GROUP в нем не пойму.
А ты SQL не знаешь?
AVK>>Не знаю, тебе захотелось по диагонали или еще как то там пиксели обсчитывать.
PD>Андрей, это уж никуда не годится. Я привел этот пример именно, чтобы показать, что когда мне надо не в "горизонтально-вертикальном", а в произвольном направлении ходить, ваш подход ИМХО пробуксовывает.
Нигде он не пробуксовывает. Тебе уже два человека написали — начальные итераторы (в моем коде Enumerable.Range) можно написать какими угодно, причем код будет короче за счет наличия в шарпе специальных конструкций для этого.
PD>Я вот одно понять не могу. Ну что стоит признать, что для определенной ситуации этот подход не очень хорош ?
О, вот очень удачно ты это спросил. Ты сам, лично, ни разу здесь не признал, что был не прав, даже если, порой, тебе приводили абсолютно неопровержимые аргументы. Зато с других ты это требуешь.
PD> Вот был бы я на вашем месте, ответил бы так — "да, для такого рода действий этот подход не годится или не очень эффективен (или еще что-то). Зато он очень хорош, для задач типа той, о которйк я написал".
У рыбы шерсти нет, а вот если бы была ...
PD>Понимаешь, для меня большой разницы между языком и библиотекой нет.
Вот вот.
PD> Linq твой останется, допустим, но ведь всех библиотек .NET FW я тебя лишу, если ты хочешь меня лишить Win32.
Я не хочу тебя лишать Win32 (боже упаси), я хочу чтобы в этой теме не присутствовало обсуждение особенностей этого самого Win32.
PD>Да пойми ты наконец, что все проходит через эту замочную скажину
PD>но если мне кто-то скажет, что в ЛИСПЕ можно записать файл, минуя в конечном счете WriteFile
А если не скажет? Сам выдумываешь оппонента и потом с ним споришь. Какая разница, через что там будет запись, если речь нге о механизмах записи файла, а о конструкциях языка?
PD>Ну это обсуждать не будем, предлагаю так, а то мы еще один флейм устроим.
Ну ты же настаиваешь, что для линка изменение порядка обхода — неразрешимая проблема.
PD>>> Вот ответь прямо — да или нет ?
AVK>>Отвечаю прямо — неважно.
PD>Не ответил
Ответил. И очень плохо, что ответ понят ты то ли не хочешь, то ли не можешь.
>>Не уводи от темы. Распараллеливание здесь в качестве примера, а не самоцель.
PD>А вот в этом не уверен.
А я уверен.
PD> IT именно это и заявил — могу , мол, легко распараллелить.
Он это заявил для того, чтобы продемонстрировать, как легко изменять функциональный код. Потому что именно наличие ФВП и возможности их комбинирования позволяет переместить в библиотеку не только конкретные алгоритмы, но и шаблоны кусков этих алгоритмов, не требуя при этом создания специальных классов или методов. Суть не в том, что это в Win32 обращается и что то там реально параллелит, а в сложности организации подобного в императивном коде.
Вот именно поэтому тебе и предлагают реализовать предложенный пример, чтобы ты понял, в чем именно преимущество ФП.
>>Если не можешь съехать с Win32, я могу в примере заменить распараллеливание на, скажем, кеширование.
PD>Ты хочешь, чтобы мы еще флейм на тему кеширования завели ? Не надо
Я хочу, чтобы ты наконец оглянулся вокруг и попытался думать чуть более абстрактно.
PD>Да просто, кто спорит.
Ты
PD> Я еще раз говорю — я совсем не противник этого.
Незаметно, если честно.
А не возникала ли у тебя мысль — а может, ничего и не надо ?
PD> Я не согласен, когда это за панацею выдается.
А кто тут выдавал ФП за панацею. Цитату можно? Вот кусочек сообщения IT, с которого эта нитка пошла:
Вот здесь два примера того, как правильные высокоуровневые конструкции могут сделать код ...
"Могут" это, по твоему, синоним панацеи? Причем, опять же, IT тебе на "могут" внимание уже обращал, так что на невнимательность списать не получится.
PD>А все же, как с диагоналями ? . Мне-то несложно.
Ну так привел бы.
PD> Ты уже засомневался
Я не засомневался, я просто указываю тебе на то, что управление приоритетами находится за рамками разговора. Никаких особенных возможностей языка оно ни при каком раскладе не требует.
PD>, и это верно, хочешь какой-то параметр (в скобках — или метод, или аттрибут или еще что-то).
Я не хочу, я просто указываю на то, что параметр, решающий твою проблему, добавить в метод AsParallel совсем не сложно (если его там уже нет) и это не приведет ни к какому ощутимому усложнению кода.
PD> Дело в том, что поручив все это системе(библиотеке, FW) и надеясь, что она сделает все наилучшим образом, ты очень скоро поймешь, что иногда да, это совсем неплохо, а иногда — ни в какие ворота.
То же можно сказать и о Win32. Но ты, я гляжу, упорно пытаешься увести разговор в сторону.
AVK>>Только даже на такой пустяковой задачке прекрасно видно, насколько твой императивнй код запутаннее.
PD>Андрей, не надо.
Надо. Именно в этом суть головного сообщения топика. Если ты этого понять не можешь — разговаривать, собственно, не о чем. Подробности Win32 обсуждай, пожалуйста, без меня, последние лет 5 меня сии знания не интересуют.
AVK>>У него алгоритм намного сложнее, а, главное, там уровень косвенности выше.
PD>У него в реальных его задачах — не сомневаюсь.
В примере тоже. Ты тут так красиво расписывал, что тебе какие то там проценты нипочем. А как до дела дошло — результата 0, одни слова.
PD> Алгоритм вычисления процентов — мб и сложнее, чем вычисления сумм, но, по правде сказать, обоим (как алгоритмам) место в средней школе во втором-третьем месяце изучения программирования.
Ну и отлично. Ждем код.
AVK>>Ты сделай сперва без распараллеливания, и мы обсудим результат.
PD>Ну опять
Конечно, а ты как думал? Ты уже неделю тут пытаешься что угодно обсудить, а кода все нет и нет.
... << RSDN@Home 1.2.0 alpha 4 rev. 1111 on Windows Vista 6.0.6001.65536>>
Здравствуйте, Sinclair, Вы писали:
S> Я уж не говорю про то, что твой лишний поток сожрал 1 мегабайт адресного пространства ни за хрен собачий, что могло кого-то вытеснить в своп.
Ну зачем же так подставляться. Павел, ИМХО, совершенно сознательно переводит любой разговор на обсуждение тонкостей Win32, а ты ему такой подарок делаешь.
... << RSDN@Home 1.2.0 alpha 4 rev. 1111 on Windows Vista 6.0.6001.65536>>
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Здравствуйте, gandjustas, Вы писали:
G>>Здравствуйте, Pavel Dvorkin, Вы писали:
PD>>>К сожалению, если поручить это все оптимизатору компилятора, то этот компилятор должен будет быть попросту гениальным, то есть включать в себя знание всех и всяческих техник, трюков и т.п, связанных и с кэшами, и с многопроцессорностью и с характером задачи. Увы, это вряд ли реально. G>>Но теоретически возможно. Что и требовалось доказать.
PD>Я пытаюсь эту ситуацию сейчас понять. В общем, видимо, с идеальной программой я не совсем прав. При бесконечном количестве ресурсов ее не может быть. При ограниченном количестве она все же существует. Додумать надо.
PD>>>Компилятор будет в лучшем случае оптимизировать "в среднем", то есть в расчете на некую среднюю задачу. И чем выше уровень абстракций, тем хуже он это будет делать. Оптимизировать цикл можно очень хорошо, а оптимизировать задачу "сделай вот это" — можно лишь на бвзе некоторых правил оптимизации общего порядка. Как только попадется нечто, что под эти правила не подходят — результат будет плохим. G>>Можно не писать то, что под эти правила не подходит.
PD>Так я об этом и говорю. Каждому инструменту — свое назначение. Где Linq, где ассемблер. кесарю кесарево, слесарю — слесарево
Из всего вышесказанного следует что программа написанная на более высоком уровне лучше поддается оптимизации.
Здравствуйте, AndrewVK, Вы писали:
AF>>Побочные эффекты в виде вывода на экран — это цель создания GUI. AVK>На основании чего ты решил, что вывод на экран это побочный эффект?
На основании определения понятия "побочный эффект". Дальше можно точно не продолжать, ты уже сказал более чем достаточно.
PD>Что-то я не понял. Вы собрались матрицы в символьном виде перемножать ? Задача достойная, но это не арифметика, а обработка текста в основном. И оптимизация совсем другого, мб, понадобится — рабботы со строками, к примеру.
Ну-ну, вообще-то символьные вычисления — это не строки. Это деревья.
Оптимизация тут вот где. Есть у нас один общий алгоритм для вычисления произведения матриц над кольцом P, где само кольцо передаётся в качестве параметра. При этом кольцо представляет из себя интерфейс. Далее, пишем реализации этого интерфейса для понятий "целые числа", "действительные числа", "выражение". Если бы это компилировали в C++, то на каждое сложение/умножение пришлось бы вызывать виртуальный метод, что не быстро. В случае с нормальным языком (тот же C#) вызов может заинлайниться. Т.е. он не просто превратится в невиртуальный вызов, а вообще для сложения будет использоваться что-то вроде add eax, abx, тут же, по месту для случая целых чисел.
LCR>>А Таня, вдобавок, хочет взять ваш алгорить, и сделать так, чтобы вместо вещественных чисел были функции, да ещё и на комплексном пространстве.
LCR>>И, наконец, Алиса, взяв ваш алгоритм в качестве процедуры, вдруг осознала, что он и является главным пожирателем процессорного времени, но специфика задачи позволяет вычислять всё произведение не сразу, а по немножку. И её осенило, что если в вашем алгоритме использовать ленивые for-ы, то всё становится замечательно.
PD>Что-то много у вас знакомых, и все они чего-то хотят
А вот жизнь такая штука. Зачем по 100 раз писать один и тот же код, если его можно взять у другого, и заниматься решением _своей_ задачи, а не решать сотни других мелких подзадач? Платят же за задачу, а не за написание велосипедов.
PD>К сожалению, если поручить это все оптимизатору компилятора, то этот компилятор должен будет быть попросту гениальным, то есть включать в себя знание всех и всяческих техник, трюков и т.п, связанных и с кэшами, и с многопроцессорностью и с характером задачи. Увы, это вряд ли реально. Компилятор будет в лучшем случае оптимизировать "в среднем", то есть в расчете на некую среднюю задачу. И чем выше уровень абстракций, тем хуже он это будет делать. Оптимизировать цикл можно очень хорошо, а оптимизировать задачу "сделай вот это" — можно лишь на бвзе некоторых правил оптимизации общего порядка. Как только попадется нечто, что под эти правила не подходят — результат будет плохим.
Думаю, не стоит недооценивать компиляторы в этом аспекте. Кроме того, у них есть достоинство — они не ошибаются. Точнее, ошибаются, как и всякая программа. Но! На компилятор рано или поздно наложат заплатку, и он не будет ошибаться. Компилятор один раз пишут, а компилируют им миллионы человек миллионы раз. А человек, если ошибся один раз, не факт, что из-за своего невнимания не наступит на те же грабли в другой.
PD>Оптимизировать задачу "постройте мне автоматически собор святого Петра" — нельзя. Для этого Браманте и Микеланджело нужны. А если эту задачу оптимизировать автоматически, то в итоге получится утепленная собачья будка размером с собор святого Петра.
Здравствуйте, konsoletyper, Вы писали:
K>Оптимизация тут вот где. Есть у нас один общий алгоритм для вычисления произведения матриц над кольцом P, где само кольцо передаётся в качестве параметра. При этом кольцо представляет из себя интерфейс. Далее, пишем реализации этого интерфейса для понятий "целые числа", "действительные числа", "выражение". Если бы это компилировали в C++, то на каждое сложение/умножение пришлось бы вызывать виртуальный метод, что не быстро. В случае с нормальным языком (тот же C#) вызов может заинлайниться.
На С++ в таких случаях пишется шаблон, реализация которого прекрасно инлайнится, причем возможности инлайнинга у современных компиляторов С++ заметно выше дотнетного или джавовского джита.
... << RSDN@Home 1.2.0 alpha 4 rev. 1111 on Windows Vista 6.0.6001.65536>>