11/17/2009 9:41:00 AM

Сегодня весь день слушал workshop по паттернам параллельного программирования.
Мероприятие состояло из трёх частей.

В первой части нам подробно рассказали зачем именно и в каком виде нужно “параллелить”. Какие бывают виды распараллеливания и т.п.
Это была самая сложная часть. В том плане, что я за ночь спал часа три только (а нечего было в самолёте высыпаться), только к утру уснул. Так что жутко хотелось спать. А так как о проблемах параллельности, мультиядерности и т.д. я уже много раз думал, и даже в этом блоге писал три года назад практически то же самое, что они сегодня говорили, то нового для меня в этой части было крайне мало, приходилось буквально заставлять себя держать глаза открытыми и открывать их, если всё же закрылись.

Хотя и из этой “философской” части несколько вещей показалось интересными:

  1. И Майкрософт, и Интел признают, что “затык” и проблема производительности сейчас лежит не на уровне “железа”, а на уровне софта. Представитель Майкрософт сказал прямо со сцены: виноваты мы с вами (все разработчики): мы просто не используем оптимально тех возможностей, которые даёт нам “железо”. А оно без проблем (и даже с меньшими затратами) может дать больше.
  2. Количество транзисторов в каком-нибудь Итаниуме отличается от количества транзисторов в Пентиум-4 примерно в 100 раз.
    Это значит, что вместо того, чтобы выпускать всякие Итаниумы на 2-4 ядра, Интел с тем же успехом и на том же количестве транзисторов мог (и может) выпустить процессор содержащий 100 ядер Пентиума-4. Про 80-ядерный процессор от Интел, впрочем, я тогда же писал.
    Если отвлечься от существующих проблем с софтом и вообразить, что мы можем их равномерно нагрузить – отдача во многом была бы куда лучше, чем от того Итаниума. Но такой процессор не выпускают потому, что мы сейчас не знаем, что с ним делать. Потому, что мы писали и продолжаем писать “однопоточный” софт. Поэтому Интел вынужден делать достаточно малое количество ядер (несколько-то потоков мы всё же делаем, да и несколько приложений одновременно запускаем), продолжая изголяться с частотой и другими параметрами.
  3. Но подвижки всё-таки есть: гибридные ядра вот уже появляются (это когда из четырёх ядер два “нормальные”, а ещё два состоят из микроядер, соотношение может быть 1:3 или 3:1, а могут и все 4 микроядерными быть). А это в свою очередь означает уже совсем другое количество потоков (посчитайте, по два на [микро]ядро хотя бы). Ну и количество ядер растёт – 8 есть, 16 ожидается.
  4. Софт, который пишется сейчас, скорее всего расчитывает продержаться на рынке пару-тройку лет. Даже с такими темпами роста прикиньте, то, что Вы пишете сейчас, способно ли эффективно использовать возможности процессоров, способных исполнять 128-256 нитей в параллели?
    Сколько Вы используете в своём приложении? Максимум три? Вам не кажется это смешным? То, что Ваше приложение будет точно так же тормозить на любой машине? Может пора перестать “изголяться” и пора начать думать и писать “нормально”? :)
    А ведь всё равно каждый, кто прочитает, через 10 минут откроет Visual Studio и продолжит клепать однопоточный код, подумал я. Ибо так проще и думать не надо. И это проблема.
  5. В Майкрософт серьёзно занимаются этой проблемой. Из тех примеров, что я помню: Visual Studio 2010 (которая сама написана на .NET с WPF-интерфейсом) очень активно использует Task Parallel Library (TPL), включёную в .NET 4.0 теперь. Это далеко не единственный пример был, просто я не проспал и запомнил :)

Да, про распараллеливание был ещё хороший пример приведён: докладчик показал последовательно три картинки. На первой был изображён молоток, на второй – воткнутый в доску гвоздь, на третьей – белка. И сказал замечательную фразу: “Когда у Вас в руках молоток, всё вокруг кажется гвоздём. Но не с точки зрения белки.” :)
Сказал он это к тому, что “мы дадим вам молоток, в виде TPL, OpenMP, F# с его immutable типами и т.д, но пользоваться им надо тогда, когда это имеет смысл и так, как это имеет смысл делать”.
По-русски это можно перевести как “дурная голова ногам покоя не даёт” и сказать, что броситься и заменить во всём приложении for на Parallel.For, а IEnumerable на IEnumerable.AsParallel() и “с чистой совестью” думать, что задачи распараллеливания выполнены – глупо.

Вторая часть была гораздо более интересной. Она была дивелоперской.
Человек, который непосредственно из команды разработки TPL, сделал отличный доклад, практически не имея слайдов презентации. Вместо этого он просто открыл Visual Studio и показывал, как делать нужно, как можно, как не нужно, что работает, что нет… Отлично объяснял почему именно и как оно работает, отвечал на вопросы, иллюстрируя ответы тут же кодом, запуская его и демонстрируя результат.
Мне понравилось.
Так, как тема была “паттерны параллельного программирования”, он объяснил, какие паттерны используются при разработке таких приложений, что эти паттерны из себя представляют, как они реализованы в TPL и как пользоваться этой реализацией.

Книжку по этим паттернам можно свободно скачать вот тут: http://www.microsoft.com/downloads/details.aspx?FamilyID=86b3d32b-ad26-4bb8-a3ae-c1637026c3ee&displaylang=en

Третья часть была посвящена Microsoft Windows HPC.
Мне она показалась малоинтересной, за исключением того, что я вообще узнал, что у Майкрософт есть такая версия системы, как HPC. Более того, ожидается вторая версия.
HPC – это аббревиатура от High Performance Computing, а операционная система расчитана на кластеры с большим количеством нод. Текущая версия поддерживает до 256 машин в кластере (я так понял, что не важно, сколько у каждой со��етов и ядер), вторая версия (R2 они теперь взяли моду всё называть) будет поддерживать толи тысячу, толи тысячи, я не понял. Но это всё равно много.
Оттуда можно WCF-сервисы “наружу” выставлять, обработка будет вестись на кластере (или куске кластера, как захочется). И они там тоже использовали те же паттерны параллельного программирования, хотя и без использования TPL, а гораздо на более низком уровне.

Это был просто workshop. Завтра начинается PDC.
Looking Forward.

P.S. Лос Анджелес удивил. Ладно мне коллега и босс говорили, что опасный город, я думал – австралы, не местные, побаиваются. Но когда сегодня обедал с одним местным, он открыл карту метро, провёл пальцем по половине города и сказал: “сюда вообще не надо ездить и выходить на этих станциях”… И потом когда тебе говорят “я в ЛА не использую общественный транспорт, у меня семья, дети, работа, я перемещаюсь или на машине или на такси” – это уже не просто настораживает ;)

Comments (21) -

11/17/2009 10:35:56 AM

Vadim

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

Но, с другой стороны, веб приложения распараллеливаются запросто, без какой-либо помощи со стороны девелопера. Так что, кажется мне, в результате у всех будут нетбуки с маленькими, но 2-4х ядерными процессорами с малым энергопотреблением. А большие 100-200 ядерные процессоры будут работать веб-серверами или считать легко распараллеливаемые задачи (рендеринг, предсказание погоды etc.)

В общем, 99% девелоперов будут просто писать веб приложения, а 1% будет реализовывать математические алгоритмы для работы на кластерах. Но они и сейчас это уже делают Smile

Vadim

11/17/2009 11:15:30 PM

Alexey Raga

Ну почему же никогда? Уже начали. Это уже просто неизбежно. Слишком сложно? Это, типа, лень, чтоли? Smile
Учиться надо. 20 лет назад люди смотрели на ООП в каком-нибудь смаллтолке и говорили: да ну, слишком сложно.

Просто для начала нужно, наверное, перестать думать в терминах "для того, чтобы распараллелить мне надо создать поток, потом его синхронизировать и т.д.". Эффективно человек сделать этого не может.
К счастью, создавать фоновый поток и исполнять в нём кусок кода - это всего лишь один способ распараллеливания. И, если делать в лоб, то далеко не самый оптимальный.

Есть же разные другие варианты. Например - Single Process Multiple Data.

Вообще говоря, надо просто перейти на другой уровень абстракции. Например, декомпозицию делать на основе "тасков". Это достаточно просто сделать, не так ли? Да, по-другому. Но - просто.

А сделать некий фреймворк, который умеет исполнять таски в разных (только этому фреймворку ведомых, кстати) потоках - это уже дело техники. И такие фреймворки есть, и не один.
Именно это делает CCR (и на его основе построены сервисы Windows Live, кстати). Ничего невозможного, работает уже сейчас.
Именно это делает TPL, который уже включён в .NET Framework и на основе которого построен PLINQ. Тоже ничего невозможного, работает уже сейчас.
Если Вы возьмёте всем известный Paint.NET - то он отлично умеет параллелить свои задачи.
Алгоритмам, паттернам, подходам, логике - уже лет десяток, наверное, если не больше.
Посмотрите те же паттерны SPMD, Map/Reduce, ActiveObject... Когда это ещё всё было придумано.

Что же качается нетбуков и прочего - то восьмиядерные десктопные машины - это уже сегодняшний день. Каждое ядро - минимум два потока. Если это микроядро - то минимум 2*количество микроядер.
Да Вы и сами посмотрите, насколько работает Ваш процессор?
Десктопных приложений никто не отменял. Тот же офис - живее всех живых. И он, кстати, активно использует параллельные алгоритмы, начиная с процессов загрузки docx всяких: там параллельно идёт распаковка, чтение, отрисовка того, что уже готова, спеллчекинг, и т.д.
Игры всякие - тоже никто не отменял. Обработку изображений, видео - тоже смысла никакого выносить в интернет нету.

Да и с тем, что веб-приложения "распараллеливаются" я бы поспорил. То, что каждый запрос выполняется в отдельном потоке, ещё не говорит о том, что в процессе выполнения запроса совершенно необходимо тратить пару секунд в одном родительском процессе, вместо того, чтобы использовать несколько и сократить время выполнения до 10 милисекунд. Никаких валидных причин НЕ делать этого нет. "Лень" и "я не умею, учиться надо" за валидные причины не считаем, понятно.

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

Словом, работа у нас такая.
Есть потребности, их надо выполнять. Не важно, что придётся думать иначе.

Alexey Raga United States

11/17/2009 11:37:34 PM

Oleg

Я тоже сидел на этом же воркшопе (на первых 2-х частях).
Вторая часть воркшопа была отличной - быстро, по делу и все точно. Этот программер реально хорош.

Oleg Finland

11/18/2009 5:28:30 AM

Vadim

Ну смотри, есть задача распарсить xml например. Ее очень сложно разбить на таски, потоки, любые куски просто потому, что парсинг каждой следующей строчки зависит от результата парсинга предудущей. Да, можно разбивать на мини потоки и выполнять их параллельно в тех редких случаюях, когда это возможно, например атрибуты одной ноды друг от друга не зависят (и их можно все легко выделить, в отличии от поддеревьев например). Но если человек будет делать это вручную, даже не оглядываясь на процессы и нити, он легко привнесет неимоверное количество багов просто потому, что код станет в десятки и сотни раз сложнее. Возможно когда-нибудь кто-нибудь сделает систему автоматического распараллеливания задачи, может быть Intel продвинет свою transactional memory, но мне почему-то кажется, что квантовые компьютеры появятся быстрее, чем это произойдет.

С другой стороны, скомпилировать С++ проект параллельно - нет ничего проще. Каждый файл слабо зависит от остальных и их можно компилировать одновременно.

То есть, есть задачи, которые распараллелить сложно, есть задачи, распараллеливающиеся тривиально. Фишка в том, что все, что может быть распараллелено уже выполняется в несколько потоков. Компиляция, рендеринг, игры, обработка мультимедиа и фотографий, там, где есть четко распределенные независимые задачи и нужна скорость. Там, где нет такого распределения, не будет параллельности исполнения до тех пор, пока компилятор сам не начнет распараллеливать код. Просто потому что никто не будет тратить лишний час и усложнять структуру программы ради того, чтобы цикл в 5 итераций исполнялся параллельно и занимал на 0.00001мс меньше.

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

Про "надеятся на кластеры" я как-то не совсем понял, они же в общем-то везде сейчас, зачем на них надеятся? Редкое веб приложение с хорошей аудиторией обходится одной машиной, как правило там их две-три, нормальный такой маленький кластер. С другой стороны, я не вижу отличия одной машины со 100 ядерным процессором и кластера из 100 машин, ну кроме того, что кластер медленее.

Это я все к тому, что думать иначе не придется. Кому-то уже давно пришлось, разработчикам OS и SQL серверов, программистам игр и мультиков. Остальным особо не зачем, даже со 100 ядерными процессорами. Максимум, на отдельные процессы разбить приложение придется, злобно ругаясь на любителей синглетонов.

PS. Да, 100 Pentium IV на одном кристалле мы никогда не увидим. Хреновая архитектура у него была, Pentium III используется в новых процессорах (и Pentium II в Atom)

Vadim

11/18/2009 5:51:29 AM

Vadim

Забыл написать о другой проблеме ручного распараллеливания - процессор, как известно, выполняет одновременно не более 2 * (количество ядер) потоков, а если их больше, он начинает тратить свое время переключаясь туда-сюда. Казалось бы, все равно нужно использовать ThreadPool и указать ему оптимальное количество ниток. Но, если вспомнить, что приложение в системе-то не одно, получается, что оптимальное количество ниток для каждого процесса постоянно меняется в зависимости от загрузки системы, задач ввода-вывода, количества запущенных приложений etc. То есть у программиста непосредственно программы нет никакой возможности узнать, сколько ниток нужно запустить для оптимальности вычислений.

Более того, на запуск каждой нитки (даже если это просто ждущая нитка в ThreadPool, которой передали новую задачу) уходит время, которое могло бы быть потрачено на сами вычисления. То есть, если программа может исполнятся в 1000 потоков, она будет исполнятся медленнее, чем если 100 потоков будут в цикле выполнять по 10 задач при условии, что количество процессоров меньше или равно 100. (Не учитывая задачи ввода-вывода, когда нужно больше потоков, чем ядер.)

Взять Outlook например, зачем ему 100 потоков если можно максимум 8 из них запускать параллельно в самом лучшем случае?

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

Vadim

11/18/2009 10:08:55 PM

Alexey Raga

Про HTML:
А ну и что, что делается "отдельно". Оно всё равно делается в _одном_ одельном потоке.

Система "австоматического" распараллеливания невозможна просто потому, что компилятор не знает и не может знать бизнес-логики. А программист знает. И программист знает, где и какие зависимости и т.д.
И это очень легко показать.

Про задачу парсинга XML - как раз про тот же пример с docx и водом. Он так и делает: организует цепочку из нескольких потоков, которые работают параллельно: в одном идёт раззиповывание, в другом - парсинг раззипованного, в третьем - построение модели, в четвёртом - рендеринг... Они работают параллельно, не последовательно. То есть, когда рендерится начало документа - это ещё не повод думать, что закончилось раззиповывание и парсинг исходного файла.
И я не вижу (и никто не видит) никакого смысла говорить, что "давайте будем делать это в одном потоке потому, что в будущем всё будет на кластерах".
То же про использование GPU - там много ядер, много потоков. Грех не использовать.

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

Про веб-кластеры: так ведь это другое. Такие кластеры везде, но это просто load ballancing и т.д.
Понимаете, если я, например, отсылаю сообщение в моём веб-приложении. Это сообщение проходит при отсылке какую-то пост-обработку, на нём запускаются определенные workflow, делаются pdf-снимки, идёт полнотекстовое индексирование, я не знаю, что ещё.
Это занимает всё, скажем, половину секунды.
Теперь я делаю простой импорт: пользователь загружате CSV-файл, в котором каждая строка - сообщение, которое должно быть отослано таким вот образом. Сообщений этих там.. Ну, скажем, 120.
Скажите мне, есть ли смысл заставлять пользователя ждать минуту в то время, когда можно сделать это параллельно очень существенно быстрее?

Alexey Raga United States

11/19/2009 1:46:45 AM

Vadim

Вот смотри, все говорят, что функциональные программы легко распараллеливаются. И это действительно так. Причина при этом очень проста, у них нет side effects. И поэтому компилятор может запускать выполнение разных функций параллельно, совершенно точно зная, что у него не возникнет проблем с доступом к общим данным, потому что таких данных не существует. (В F# существуют, и это его большая проблема)

Возьмем обычное C# приложение. Часть кода будет использовать общие данные в виде синглетонов и просто расшаренных объектов, а часть не будет. И компилятор статичестким анализом вполне может выделить куски, которые не используют общих данных и могут выполнятся параллельно. Знание бизнес-логики ему для этого не нужно.

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

Вообще, LINQ.ParallelWith тоже не знает бизнес-логики, но при этом работает.

А теперь давай посмотрим на пример с парсингом docx. Там есть 4 потока по твоей модели, даже современный процессор будет половину времени просто простаивать. А компилятор может разбить эту же задачу на 1000 микро-потоков, которые будут выполнять по десяток операций каждая.

Да что там говорит, процессор сам уже давно исполняет по 2-3 инструкции параллельно даже в пределах одного потока, без знания бизнес-логики, конечно Smile

С pdf конечно ты прав, и в Гугл один запрос занимает сотни серверов, раскиданных по всему миру. Но это же редкий случай. 99% - забрать данные из БД -> преобразовать из в html. А оптимизировать всегда нужно под самый общий случай.

C GPU отдельный разговор, там можно только считать. Считать в современном программировании приходится довольно редко, поэтому 90% приложений CUDA никогда не будут использовать.

И вообще, хватит меня на Вы называть, ты меня лично знаешь Smile

Vadim

11/19/2009 9:45:43 PM

Alexey Raga

Про immutable-данные и состояние я уже говорил и не раз, это к нашему вопросу не относится.

Повторюсь, компилятор не может знать, что можно параллелить, а что - нет. Сами подумайте, откуда компилятору знать, имеет ли смысл порядок обработки коллекции, например? Если я в своём цикле формирую и отправ��яю сообщение, или вызываю веб-сервис, или просто посылаю win message, откуда компилятору знать, что это можно делать параллельно, что порядок операций не имеет смысла?
Проблем с "автоматическим" распараллеливанием очень много, "общее состояние" - это не единственная проблема. В противном случае, раз это всё "прошлый век", покажи мне компилятор "века настоящего", которым ты пользуетешься и который может это делать Smile


Про LINQ.ParallelWith - он тоже не знает логики. Её знает программист. Который совершенно явно и говорит - ParallelWith. Тогда уж и компилятор может догадаться Smile

Да, в docx-парсинге моей модели (на самом деле это человеки из MS так сказали) есть минимум 4 потока. Может быть больше, ибо рендеринг модели может быть распараллелен, я не знаю.
Но, вспомним, с чего ты начал: "писать параллельный код программисты никогда не начнут, слишком сложно". Блин, а они пишут, заразы! Smile И четыре потока почти в четыре раза быстрее, чем один! И это имеет смысл, и не слишком сложно, вроде бы, и не надо ждать "компиляторов века грядущего", и не надо отнекиваться утверждениями "мультиядерность - фигня, 99% будет на кластерах, причём не вычислительных, а веб-кластерах" Smile

Про 99% задач "забрать данные из БД -> преобразовать из в html" - возможно, ты имели в виду ваших задач? Smile На моей текущей работе это далеко не так (а на предыдущей html вообще не было).
Серьёзно, очень, очень много программистов пишут "настольные" приложения. Даже Сильверлайт уже позволяет настольные приложения писать.
Очень много существует в мире программистов, которые пишут всякие бизнес-логики, которая достаточно критична к производительности.

И ещё больше пользователей, которые ругают последними словами программистов, когда покупают новый компьютер, а программа как работала медленно, так и продолжает это делать. Понаблюдай за загрузкой ядер своего компьютера.
И можно считать, что в Интел работают очень глупые инженеры, но вместо того, чтобы разработать супер-компилятор они разрабатывают (и будут разрабатывать, если не врут) мультиядерные процессоры.
А код параллелить придётся нам. И нет смысла этого не делать.

Alexey Raga United States

11/20/2009 3:24:09 AM

Vadim

immutable-данные - это как раз ключ к параллельности. Есть изменяемые данные - нет параллельности. Потому что будут локи, а это гарантированный источник ошибок. Я как-то писал программу с 200-300 потоками, и там всего было строчек 10 с локами. Я три месяца выуживал ошибки из этих 10 строчек. И все равно, когда ее через год ее на другой машине запустили, мне пришлось пару дней выуживать новые баги.

В этом вся соль, понимаешь, если 100 потоков обращаются к двум-трем расшаренным местам в памяти - очень, очень, очень сложно проиграть все возможные варианты у себя в голове. Если есть 2-4 потока, это почти тривиально. Если их больше - это становится просто неосуществимо.

Поэтому уже давно пытаются придумать способы избежать локов. И пока есть всего лишь два пути, неизменяемые данные или transactional memory. Оба пути предполагают отказ от так нами всеми любимого императивного программирования. Ты готов завтра начать переписывать свой код хотя бы на F#? Я, например, с удовольствием, но мне потом голову начальник открутит, особенно когда попробует новых программистов в проект набрать.

Но если посмотреть с другой стороны, почти никому это не нужно. Если нет гигабайтов данных для обработки, однопотоковое приложение достаточно быстро и даже начинающий программист сможет его понять и исправить в нем ошибки. В веб приложениях load balancing гораздо важнее распараллеливания кода контроллера, потому что количество данных для обработки ограниченно сверху пропускной способностью интернет каналов. 2MB HTML загружается очень долго и всем действует на нервы, уж поверь мне.

И потом, я не верю в скорое пришествие 100 ядерных процессоров. 16 и 32 ядра я скорее всего еще успею увидеть. А вот больше вряд ли, он просто не будет успевать выхватывать куски программы для выполнения из общей шины, и бедному винчестеру и даже SSD придется очень плохо в такой ситуации тоже.

PS. Я dotnetrocks за прошлый год слушаю, и что бы ты думал? Они тоже все время обсуждают F# и многопроцессорность. Но за этот год _ничего_ нового не появилось.

PPS. Silverlight на десктопе - это запоздалый ответ на Adobe AIR. Оба не получат большой доли рынка, никому из нормальных пользователей это не нужно. Ну MS еще очень постарается на базе Silverlight новую Mobile OS сделать, но тут у них тоже ничего не получится. Во-первых, Mobile OS индусы занимаются, а во вторых Google _платит_ производителям телефонов под Android.

PPPS. А да, Moonlight, клон Silverlight, мало того, что был на десткопе раньше, чем сам Silerlight, так его еще усиленно пытаются продвигать как новую платформу для приложений под Линукс. И тоже - никакого прогресса, никто не интересуется.

Vadim

11/22/2009 1:10:57 PM

Alexey Raga

Про иммьютабилити - ещё раз, это отдельная история, я то же самое уже писал тремя годами ранее, что ты тут повторяешь Smile Не знаю зачем ты пытаешься мне доказывать то, что я сам же и говорю ;)
Другое дело, что иммьютабилити накладна.

Про ядра: 32 ядра - это минимум 64 потока. Это уже очень немало.  А если говорить о микроядрах - то и того больше.
Про 100 ядер никто не говорит - это был гипотетический пример, показывающий, что на том же количестве транзисторов (считай, с той же степенью сложности) можно так сделать. Не более. Повторюсь - с той же степенью сложности. Всякие комментарии о неэффективности архитектуры вот именно П4 и т.д. к этому отношения не имеют, читай внимательнее ;)

Про "ничего не сможет понять" - поэтому и идут разговоры о повышении уровня абстракции. Это для того и делается, чтобы упростить понимание сложных вещей.

Про "ничего нового" - это тоже не совсем правда. Тут и планировщик процессорного времени поменяли под это дело неслабо в ОС, и CCR сделали (замечательная штука, я работал с ней, нормально всё понимается), и TPL вот сделали, и OpenMP сделали, и Intel разработал целый ряд инструментов (для программиста) для "распараллеливания".
Делается, конечно. Просто вот некоторые говорят "да ну их, всё это неправильно, нафиг, декомпозицию нормальную мне делать лень, пойду писать однопоточный код".

Про локи: в этом и есть проблема. Отсюда все разговоры про task oriented programming и идут. То, что ты говоришь - оно не ново и очень далеко не ново. Помнится, если память не изменяет, Херб Саттер выступал года этак три назад по поводу этой проблемы. И говорил совершенно то же самое: ни один нормальный человек не в состоянии нормально написать многопоточную программу на логике "локов". Оно просто не уложится в голове и багов будет немерено.
Вот именно поэтому и делают вещи типа TPL, поэтому и повышают уровень абстракции, поэтому и говорят об иных принципах декомпозиции.
Поэтому вменять "я писал 10 локов и не осилил" никому не надо. Никто не предлагает тебе так делать. Совсем наоборот, предлагают так НЕ делать.

Про Сильверлайт - да получится, никуда не денется.
То же говорили про дотнет фреймворк - и что? Эдоб Эйр уже проигрывает Сильверлайту по доле рынка. С выходом 3-й многие очень серьёзные сайты, отдающие видео в интернет, стали использовать сильверлайт из-за возможностей зума и изменения качества потока "на лету" в зависимости от скорости соединения.
На PDC новый интерфейс продемонстрировал Facebook. Я напомню - Facebook - это не "вконтакте" какой-то там, у него ОГРОМНАЯ аудитория.
Новый интерфейс обладает рядом уникальных фич, кроме того, он написан уже как внебраузерное приложение.
То есть, я уточню, это фактически десктопное приложение, которое работает одинаково на Mac и на PC, требует для установки всего лишь 4.8-мегабайтового Сильверлайта. Который уже установлен примерно на 45% PC-компьютеров, согласно статистике.
Ну и всякие другие интересные фичи типа дран-н-дропа, например, файлов из файловой системы в сильверлайт-контрол.. Да много там чего. Всё это очень привлекает бизнес.
Для примера: наш шеф принял решение, что для пользования нашего продукта клиенту необходим сильверлайт. Нет - пусть ставят или "идут лесом". Поверь, с нашим продуктом работают очень серьёзные люди из очень серьёзных организаций, с очень серьёзными контрактами и очень серьёзными деньгами (��тоимости их проектов измеряются от нескольких миллионов до биллионов долларов).
Пойдёт Сильверлайт в жизнь, куда он денется. Не считаешь же ты, что Майкрософт умрёт, не продвинув его на нужный уровень Smile

То, что "империя зла", я имею в виду Гугл, платит кому-то за что-то - это ничего не значит. Они платят, Андроид вот уже года два как существует, а телефон я в магазине видел всего один. Да и тот с бумажкой вместо экрана. А чтобы кто-то пользовался, так, на улице или в поезде - не видел ни разу.
С другой стороны Эппл не платит, а даже берёт с разработчиков деньги - за лицензию 90 баксов в год + нехилый процент с продаж. И что мы видим? Айфон у каждого второго, если не чаще. У некоторых по два. Скотт Гасри на том же PDC оперировал с четырьмя Smile

А то, что занимаются индусы - это что-то значит?

Всякие "моны" и "лайты" Мигель может продвигать сколько угодно (кстати, я лично из его рук получил диск с Моно 2.4), они не слишком конкурентоспособны, так как находятся в роли догоняющих. И отстают достаточно сильно.
Хотя, у них есть некоторые фичи, которых нет у Майкрософта и они (фичи эти) достаточно интересны.
Другое дело, что фичи эти сами по себе значат не много.

А сказать, что "сильверлайтом никто не интересуется" - совершенно нельзя.

Alexey Raga United Kingdom

11/22/2009 1:37:23 PM

Alexey Raga

Да, и я не понял, при чём тут количество мегабайт в HTML?
Ты вот так вот взял - и проигнорировал мой простой пример из моей повседневной реальной практики с отсылкой сообщения.
Сообщения два байта может занимать, может - 20, а может - 200. На количество этапов процессинга оного влияет совершенно не это. А этапов может быть много. И если делать их последовательно - это занимает определённое время. И не важно, сколько у меня серверов в ферме и насколько замечательный там баллансинг. Даже если я Единственный Пользователь На Планете, а все остальные спят - никакие фермы меня не спасут и я буду сидеть и ждать, пока сообщение пройдёт.

Или вот финансовые штуки, например, предсказания и стратегии. Речь там идёт о простой математике, ты же учил её в университете? Берутся начальные данные, потом рандомная величина, получается новая константа, подставляется в то же выражение вместо той рандомной величины, получается новая константа и т.д. Это математика, точность зависит от того, какие данные имеются и от того, как много итераций ты успеешь сделать за необходимое время. Это простой пример, конечно. В реальности и константы - не константы, а функции, и выражения различны и всё такое. Но факт остаётся фактом: вся эта штука очень мало зависит от того, сколько машин в веб-ферме и уж совсем не зависит от того, сколько данных пришло из HTML Smile
Я даже представляю, как ты начнёшь фразу с "99% программистов...", поэтому спешу обрадовать: такими (или подобными) вещами занимается львиная доля программистов в Австралии, подозреваю, что почти все программисты Люксембурга и Швейцарии и очень, очень много в США. Это я про банковскую сферу.
А есть ещё другие сферы - страхование, например.
Телеком, чего греха таить. Это вообще страшная штука - спустись на уровень пониже - и ты _обязан_ гарантировать ответ железу в течение n милисекунд. Ну, просто оно больше ждать не умеет и не будет.
Или на самом высоком уровне там же: мы делали инструмент, ну, типа visual studio, но для наших нужд. Там без многопоточной обработки просто не обойтись - ты уснёшь ожидая. А если не уснёшь ты - то не усну и я, потому как ты же меня и будешь материть отчего оно так медленно работает.
Там ВООБЩЕ нет HTML-страниц, там просто нужно обрабатывать много данных, делать это постоянно, плюс поддержка многопользовательской функциональности, плюс, плюс..

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

Alexey Raga United Kingdom

11/22/2009 2:38:22 PM

Vadim

Да я же не спорю, что многопоточность - это круто и быстрее, чем один поток. И что есть области, где от скорости многое зависит, и там нужно оптимизировать все, что можно, в том числе писать многопотоковый код. Но это не всем и не всегда нужно. Далеко не каждый программист в своей жизни будет оперировать более, чем 2мя потоками (GUI в отдельном потоке все-таки стало уже почти стандартом). Простой пример - EF в 4 раза медленнее LINQ to SQL, но ты же используешь EF. Потому что тебе так удобнее, потому что это правильный уровень абстракции для приложения, потому что приложение получается проще. Не важно, что оно могло бы работать в 4 раза быстрее. Так и с потоками. Чаще всего не важно, что приложение работает в 1 поток и использует 1/8 от мощности процессора. Главное, что оно просто устроено внутри и устраивает программиста и заказчика.

Смотри, веб-сервера уже чуть ли не с 90х годов часто имеют по 2-4 процессора, но большинство веб-приложений все равно однопоточно. И что не говори, большинство программистов все-таки пишут CRUD веб-приложения и будут писать их дальше. Индустрия большая, и веб-программирование занимает очень большую ее часть, больше чем инвестиционные банки. Да что там говорить, программистов под iPhone уже наверняка больше, чем сотрудников у трейдерских компаний. А iPhone даже garbage collector приличного не имеет, не то что многопоточность.

А в веб-программировании, повторюсь, размер задачи ограничен размером выдаваемого HTML. Чтобы сгенерировать 2MB текста, скорее всего не придется перелопачивать гигабайты данных, а обработать только очень маленький кусок от них. Для чего многопоточность не потребуется.

CCR и TPL - очень хорошо. Но это не новые идеи, просто небольшая надстройка над старыми. Это не поможет программистам писать хороший и надежный многопоточный код. Все равно есть возможность сломать приложение, обратившись к общим данным без локов и даже не заметить этого. Ты писал когда-нибудь на C++? Там тоже можно случайно все сломать одной строчкой, да так, что потом будешь месяц искать причину. Это очень плохо для нервов. Многопоточность в современном виде, даже с надстройками, равнозначна С++ по надежности.

Есть выход, конечно, Erlang например, там нет общих данных и нет такой проблемы. Но сколько разработчиков пишет на нем, а сколько на C# или на PHP? Lisp, Haskell, F# наконец, все более-менее решают проблему многопоточности, но у них почти нет последователей. Зато есть у С#, в котором нормальной безопасной многопоточности никогда не будет.

В общем-то я просто против лозунга, что нам всем _придется_ писать многопоточный код. Нет, не придется. Даже если будет 100 ядер, все равно не придется. Точнее не всем. Еще точнее, тому, кому придется, уже сейчас приходится. И 10 лет назад приходилось.

Vadim

11/22/2009 2:54:10 PM

Vadim

Да, про Силверлайт. Он _возможно_ будет популярнее Abobe AIR, он скорее всего будет стоять у всех гиков и в enterprise секторе, но он никогда не затмит обычный Flash. Youtube не будет транслировать видео в Silverlight, на iPhone и Android silverlight не будет работать. А Flash будет. И сейчас и через 5 лет, если Adobe случайно не загнется, все крутые новые фишки будет выгоднее выпускать на Flash, а не на Silverlight. Потому что у Flash гораздо больше аудитория. 100% против 45% Smile Хотя, обычный JavaScript вместе с Сanvas и Video элементами скорее всего вытеснят Flash, Google работает над этим.

А WinMo загнется совсем уже в ближайшем будущем. Потому что ты не совсем понял, "империя зла" платит не разработчикам, она платит производителям железа. Чтобы поставить Windows Mobile производитель должен заплатить MS с каждого устройства довольно круглую сумму, MS на этом зарабатывает в конце-концов. А если поставить Android, Google будет платить производителю определенную сумму с каждого устройства.
Да, им не победить iPhone, но это не их цель. У них цель - победить всех остальных. В том числе MS. Ну скоро еще TomTom и Garmin, но это из другой оперы Smile

Vadim

11/23/2009 8:24:40 AM

Alexey Raga

Про веб-приложения - отчасти я согласен. Просто потому, что каждый запрос - это и так отдельный поток. Согласен, что в достаточно большом количестве случаев большего там не надо. Но это не означает, что нигде не надо. Есть очень большие области, где надо.
Кроме того, в Enterprise даже в случае веб-приложений очень часто в системе существуют windows services, получающие информацию из service broker queues и обрабатывающие её. Там многопоточность очень важна. Пример, который есть очень много где: создание полнотекстового индекса по загруженным файлам. Файл надо обработать определённым фильтром (вытащить контент), обработать этот контент, построить индекс, запихать в хранилище. Обработка асинхронна, задачи - в очереди, сервис обрабатывает очередь.
И такого очень много.
То есть, я согласен, что в случае веб-приложений какое-то распараллеливание есть out of box, но и его очень часто не хватает. Далеко, оооочень далеко не всегда производительность упирается в скорость передачи по сети.

Надстройки вроде CCR и TPL - это, конечно, компромис в какой-то степени. Но писать понятный и распараллеливаемый код они всё же помогут. И помогают, а почему нет?
Самый-самый примитивный пример: foreach(var item in items.AsParallel()) { DoStuff(item); } - очень даже понятно и очень даже помогает.
И это даже не сам TPL, это PLINQ, который надстройка над TPL.
Сделав нормальную декомпозицию с учётом shared state можно просто и понятно распараллелить многое с использованием CCR и TPL. Гораздо проще и гораздо понятнее, нежели без оных. И при этом никаких локов писать не надо.

И, когда я говорю, что придётся, я имею в виду тем, кто заботится о производительности, тем, для кого она критична.
Если твоя задача - выдать 2КБ текста в HTML без какой-либо обработки - то да, тебе, возможно, без разницы - за тебя это распараллеливание уже написали в IIS.
Начни ты писать, скажем, десктопные приложения - типа Visual Studio, или что-то для финансового сектора, или делать обработку данных - и тебе придётся тоже.

Про 10 лет назад - приходилось, конечно. Только вот и задачи стали с тех пор сложнее, и возможностей больше. И нет никаких причин эти возможности не использовать.

Alexey Raga United States

11/23/2009 12:07:41 PM

Vadim

Я очень не завидую тем, кто по настоящему заботится о производительности Smile Им очень не повезло, им придется писать многопоточный код на C++ Smile Там даже Map-Reduce не очень помогает, потому что память приходится самому убирать, это просто гигантский источник ошибок.

Vadim

11/23/2009 12:43:04 PM

Alexey Raga

А с чего вдруг С++ всплыл?
Я не знаю, есть ли что-то task oriented на С++, наверняка есть. Я не помню, есть ли в unmanaged C++ TPL, например, но уверен, что что-то подобное существует, уровнем повыше OpenMP.
Про С++ - послушай Саттера, кстати.
video.google.com/videoplay
Вот. Про то, что это за чувак, думаю, рассказывать не надо ;)

Но язык тут, на самом-то деле, не очень существенен.
Существенно другое, что я и пытаюсь сказать: в настоящее время мы имеем достаточное количество ресурсов, которые не используем. Начни мы их использовать - и наши приложения будут производительнее.
Например, построение дерева объектов в "студии", которую мы рефакторили на прошлой работе, могло занимать несколько десятков секунд. Это было написано на С#. Можно было переписать на С++, конечно. Отчего же и нет. Только быстрее бы оно от этого не стало.
А вот использование "многопоточных" алгоритмов в том или ином виде дало существенный прирост производительности.

Что значит "даже map-reduce не помогает" - я не понял. Почему "даже" и с каких пор map-reduce стал панацеей от всех бед Smile Ну да бог с ним Smile

В общем, the point is: есть куча ресурсов и нет никаких причин их не использовать. Во всяком случае ты ни одной такой причины не назвал. То, что где-то есть какие-то веб-приложения на PHP формирующие 2КБ страничку я причиной считать не буду, ага? Ибо это как пример с молотком, гвоздём и белкой - если это не даст никакого выигрыша - то и не за чем.
А вот если даст - тут уже совсем другой разговор получается.

Alexey Raga United States

11/23/2009 12:59:27 PM

Alexey Raga

А, чего я сюда залез-то.
Байка о том, что EF медленнее чем L2SQL в 4 раза - она, похоже, не верна.
Я говорил с ребятами, проводившими тесты при выборе архитектуры (меня тогда тут не было). Ничего подобного у них при тестировании не получалось. Производительность примерно та же самая. А с учётом возможностей кеширования контекста EF (хотя оно и крайне убогое) получается, что.. ну, ты же понимаешь, что такое кеш Smile

Вот на наших задачах, наших схемах и наших данных L2SQL преимуществ не имеет. А вот недостатки - это пожалуйста. Потому и был выбран EF.

Кроме того, если говорить о дельте производительности в абсолютных цифрах - то они всё же смешные. И составляют крайне малые доли в общем процессе "подготовка запроса - выполнение - обработка результата".
То есть, использовать эту байку в виде "возьми L2SQL и всё станет в 4 раза быстрее" - смешно и глупо, так как подготовка запроса - это копейки в сравнении со всем остальным, как я уже сказал Smile

Alexey Raga United States

11/23/2009 1:25:05 PM

Vadim

Ресурсы можно по разному использовать. Можно их тратить на вычисления, а можно на развертывание уровней абстракции. Ruby успешно загружает компьютеры, гораздо лучше, чем .Net или C++, но вычислений при этом проводит куда меньше.

Когда есть большая задача, как раз и проверяется, насколько серьезно компания относится к скорости ее выполнения. Если серьезно - только С++ с минимальными уровнями абстракции, если не очень, тогда C#, может быть многопоточный.

Если что, внутри Google и большинства финансовых институтов, насколько я могу судить по seek.com.au, все написано на C++. Потому что им скорость важнее легкости написания и поддержки.

Тут просто есть какая-то странность, которая мне не нравится. MS предлагает все новые и новые уровни абстракции, которые делают приложения все медленее и медленее, а расплачиваться хотят заставить обычных программистов, которым придется писать многопоточный код. С локами, кстати, от них никуда в реальном приложении не денешься, у меня есть такой опыт.
Мне кажется это неправильный путь.

Но я же не буду тебя отговаривать писать многопоточный код, правильно? Ты прав, нет причин не использовать потоки и параллельность исполнения. Но это просто одна из возможных оптимизаций, к ней нужно относится так же, как к другим оптимизациям. То есть, пока профайлер не скажет, что именно в этом куске кода все плохо, зачем запускать там несколько потоков и серьезно усложнять себе жизнь? Может быть, проще написать компонент на C++? Или применить другой алгоритм? Или отказаться от абстракции в данном конкретном маленьком кусочке кода? Или вообще закешировать результат? Есть столько разных способов сделать код быстрее Smile

PS. Да, если бы переписали на С++, было бы _существенно_ быстрее.

Vadim

11/23/2009 3:00:02 PM

Vadim

Леха, я тесты конечно сам не писал, но вот тут (toomanylayers.blogspot.com/.../...linq-to-sql.html) чувак прямо с кодом результаты предоставляет, и у него получается, что не только во время подготовки запроса L2SQL быстрее. Вообще, чисто логические умозаключения меня приводят к такому же результату, руками SQL выгоднее пока что писать.

Vadim

11/24/2009 12:52:09 PM

Alexey Raga

Ну ты послушал, что Саттер говорит? Вот тебе человек из мира С++, человек в этом мире не последний, имеющий не последнее слово в комитете стандартизации оного и всё такое.
Он прямо говорит: "на С++ у меня лично мозгов написать логику на локах и синхронизации не хватит". И ни у кого не хватит, отсюда и разговоры о повышении уровня абстракции и о несколько иных принципах декомпозиции.

Кстати, повышение уровня абстракции вовсе не означает потерю производительности. А если мы скажем: "ну его нафиг, С++ этот, ASM - полный контроль и полная скорость!". Иди, пиши Smile Посмотрим, что ты напишешь, в каком виде, как это будет работать, как поддерживаться и в какие сроки ;)
Это, кстати, ни капли не утрированный пример. Тот же телеком или те же железные штучки. Какой там С++, что ты. Максимум - С. С++ слишком медленен и накладен.
Так почему же ты говоришь о С++, а не о С? И дальше, почему С, а не ASM? Smile

Лично я считаю, что дело не в языке. Я понимаю, ты успешно игнорируешь мой пример, но всё же, как ни оптимизируй его в один поток - а в 4 всё равно будет в 4 раза быстрее Smile На чём ни пиши. Тот же Саттер - пищет на С++. Куда его пошлём? ASM? Smile

Всё гораздо проще: есть задача и есть ресурсы. И нет никакого смысла эти ресурсы не использовать. Вот и всё. Дальше - парадокс. Я даю задаче больше ресурсов, а она быстрее выполняться не хочет. Да почему же? Какая разница, пусть на ASM написана будет, не вижу никакого смысла тратить 4 секунды вместо одной.

Кстати, про "гораздо быстрее будет" - да не будет же. Проход по дереву диска с поиском всех находящихся в нём объектов, распаковкой и десериализацией файлов-дескрипторов, фильтрация и сортировка их, построение модели и отображение в дереве доступных объектов - напиши хоть на ASM хоть на Питоне последовательный код - он всё равно по производительности не сравнится с параллельным.

И речь как раз идёт о том, чтобы (и как) сделать параллельный код не усложняя себе жизнь. И это возможно таки, тот же примитивный пример с AsParallel().

Про EF, опять же, я тоже тестов не писал. Писали другие, я за что купил - за то продаю Smile
Но я видел достаточное количество тестов, которые показывают, что "фича А в 5 раз медленнее фичи Б", но при ближайшем рассмотрении оказывается, что эта самая медленная "фича А" занимает пять десятых процента операции, в которой учавствует. Да, "фича Б" может быть сожрёт всего одну сотую процента... Но сравнительно - это не те цифры, которыми следует интересоваться и не те вещи, которые нужно оптимизировать.
У нас, я так понял, тестировали какие-то приближенные к реальности вещи. Опять же, сам не пробовал, не знаю.

Alexey Raga United Kingdom

11/24/2009 1:35:36 PM

Vadim

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

То есть, как всегда в программировании, нет однозначного ответа на вопрос, работать параллельно или нет. И я просто говорю, что можно же другие способы оптимизации использовать Smile В Web программировании у остальных ядер все равно работа будет. В не-веб возможно не будет Smile
И скорее всего, на небольших задачах, С++ в один поток отработает быстрее, чем C# в 2. Ну хорошо, от задачи зависит, конечно, но вот с деревом например - наверняка. Такие задачи по обработке чего-то большого в памяти на C++ очень хорошо работают.

При чем ты же согласен со мной, что сроки и maintainability чаще всего важнее скорости работы. Но почему-то не согласен с фактом, что даже с TPL многопоточные приложения займут больше времени на разработку и будут менее поддерживаемые. Они будут принципиально сложнее, настолько, что надо сначала взвесить все возможные варианты. Ну, то есть, я не на 100% уверен, что параллельный код на TPL будет сложнее, чем обычный код на C++, но я же и говорю, надо все варинты взвесить Smile

PS. Да, все-таки С более-менее умер. С++ чаще быстрее (за счет шаблонов и inline методов), ну и ООП всем нравится Smile

Vadim

Comments are closed

Powered by BlogEngine.NET 2.5.0.6

About the author

Alexey Raga Alexey Raga
.NET software developer.

E-mail me Send mail

Twitter


Recent posts

Archive

Disclaimer

The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

© Copyright 2012

Sign in