Comments 81
Неплохая статья. Спасибо.
Мне одному кажется странным утверждение, что поток является низкоуровневым объектом в многопоточной архитектуре?
Поток - это низкоуровневая сущность. Существует дизайн паттерн "активный объект", и вот он уже предендует быть высокоуровневым. Высокоуровневость обеспечивается тем, что не сказанно, должен ли этот паттерн быть реализован при помощи отдельного потока в том-же процессе, отдельного процесса, или вообще процесса в удалённой среде.
Мне честно говоря, тоже. Не понимаю, что можно сделать выше и проще тех же критических секций. Это ведь уже элементарные операции, которые дальше никуда не объединить. Какие могут быть фреймворки? Просто объясните, что в таком фреймворке будет.
Статья большая и красивая, а смысла сама суть не раскрыта.
PS Я писал на Си и Яве довольно много многопоточных приложений, так что я, в принципе, "в теме".
Статья большая и красивая, а смысла сама суть не раскрыта.
PS Я писал на Си и Яве довольно много многопоточных приложений, так что я, в принципе, "в теме".
Вы всё перепутали :) Элементарные операции и есть низкоуровневые :) Выделение и освобождение памяти это тоже элементарные операции, и поэтому они низкоуровневые.
Наоборот :) Элементарные операции нельзя разложить :) А объеденять их можно сколько душе угодно. Элементарные операции для того и нужны, что-бы их объеденять в более сложные :)
Это ведь уже элементарные операции, которые дальше никуда не объединить.
Наоборот :) Элементарные операции нельзя разложить :) А объеденять их можно сколько душе угодно. Элементарные операции для того и нужны, что-бы их объеденять в более сложные :)
Вы уж во втором абзаце скажите что Intel перестали поднимать частоту потому что пришёл предел воздушного охлаждения, физические ограничения кремния. В оригинальном варианте можно подумать что Intel решили клепать многоядер вместо увеличения частоты…
А так очень всё классно описано и интересно. Спасибо!
А так очень всё классно описано и интересно. Спасибо!
На самом деле я просто не знал реальную причину, по которой Intel решили клепать многоядер, отказавшись от того что-бы гнать частоту. Вернее, я знал, что это какая-то невозможность обусловленная законами физики, но не знал что это именно предел воздушного охлаждения, поэтому писать не стал. Но с вами согласен, что упомянуть об этом нужно.
Почитаю об этом по подробнее и поправлю статью.
Почитаю об этом по подробнее и поправлю статью.
во-во. Только уже не кремния, а углерода. Один мой знакомый, серьезно занятый в "железной" индустрии еще годе в 2001-м вещал мне о пределе в 3-3.5 МГ и о грядущей многоядерности. Так что КорДуо у нас не от жизни хорошей (у Intel'a :)
Закон дырявых абстракций
Фигня, а не статья... Вы вообще хоть с какими-нибудь языками, кроме Си-подобной императивщины знакомы? Не говоря уж о том, что бы писать код на них.
Посмотрите, например, на erlang.
Посмотрите, например, на erlang.
А что erlang использует потоки операционной системы?
А при чём тут "потоки операционной системы"? Если вы по поводу использования ядер процессора, то никто не мешает запусть К нод на одной машине, где К == ядер.
А какая разница? Он использует определенную парадигму и "языковый api", а как это реализуется в конкретном случае, не имеет значения.
Вообще-то есть и большая. И разница заключается в том как оно будет масштабироваться. Если оно автоматически не умеет подстраиваться под большее число ядер это нафик не упало. Опять же что вы будете делать на NUMA архитектуре ? У AMD как раз такая архитектура.
Вывод: про erlang Вы ничего не знаете. Нахватались умных слов, значения которых не до конца понимаете и пытаететь из применить в дисскуссии...
Про erlang я спрашиваю у вас. Умеет или нет. И объясняю когда и как это может плохо масштабироваться. Если оно не умеет автоматически само окучивать большое количество процессов, то толку будет мало.
По буквам:
У ерланга нет понятия "вызов метода". У него есть понятие "передать сообщение". Кто и где обработает это сообщение вызывающая сторона не знает. На этом основывается мощнейшии возможности erlang по кластеризации. Ибо принимающая сторона может находится на другом конце света. Всё связанное с проблемами передачи данных будет сделано в рантайме.
При вызове можно явно указать, что вызов асинхронный. С.м. выше + все вкусности асинхронщины.
Через это у разработчиков системы на ерланге на халяву есть кластеризация и (практически) не ограниченное масштабирование.
А автоматическое окучивание процессоров в данном случае не нужно. Ибо а) не десктопом единым, б) если сделать автоматическое "расползание нодов", то тогда придётся делать кучу ручек для ограничения этого "расползания".
У ерланга нет понятия "вызов метода". У него есть понятие "передать сообщение". Кто и где обработает это сообщение вызывающая сторона не знает. На этом основывается мощнейшии возможности erlang по кластеризации. Ибо принимающая сторона может находится на другом конце света. Всё связанное с проблемами передачи данных будет сделано в рантайме.
При вызове можно явно указать, что вызов асинхронный. С.м. выше + все вкусности асинхронщины.
Через это у разработчиков системы на ерланге на халяву есть кластеризация и (практически) не ограниченное масштабирование.
А автоматическое окучивание процессоров в данном случае не нужно. Ибо а) не десктопом единым, б) если сделать автоматическое "расползание нодов", то тогда придётся делать кучу ручек для ограничения этого "расползания".
Да, и вообще, чисто функциональные языки программирования параллеляться просто влёт. Ибо отсутсвие сайд-эффектов позволяет оооочень многое из того, что нельзя (или очень сложно) сделать на императивных языках.
Вы не лучше аргументируете.
Кроме императивного, я знаком и с функциональным программированием и с логическим. В одной статье обо всём не напишешь, поэтому писал о мейнстриме - а именно, об императивной модели вычислений.
Хаскель ;)
Попытки упростить написание многопоточных программ и избавить программиста от низкоуровневого программирования предпринимаются давно (напр. языки Erlang и Limbo). Не насколько круто, как описано в топике, но...
В общем то все верно, ЯВУ должны прозрачно инкапсулировать работу с потоками, и тогда будет на счастье Здесь, кстати, вспоминается долготянувшийся переход на (Win)32. Вплоть, наверное, до 2000 г. сталкивался с серьезными программами, все еще в 16bit-режиме.
Так и сейчас - два(четыре) ядра, регистры 64bit, а у нас софт под i486 скомпилирован..
Я считаю, что интел должны (и сделают) аппаратное "высокоуровневое" управление потоками. Это, безусловно, скорее в помощь системщикам, нежели прикладникам, но это даст возможность создать единый механизм управления потоками во всех осях, и вот тогда это можно встраивать в язык. Не в библиотеку, а именно на уровне языка. И тогда код вида {i+=d, j+=getInput();} действительно будет выполняться параллельно. Ну и, естественно, запись вида class CMyUsefulJob :public CThead { будет инструктировать компилятор выносить код данного класса в отдельный поток.
Так и сейчас - два(четыре) ядра, регистры 64bit, а у нас софт под i486 скомпилирован..
Я считаю, что интел должны (и сделают) аппаратное "высокоуровневое" управление потоками. Это, безусловно, скорее в помощь системщикам, нежели прикладникам, но это даст возможность создать единый механизм управления потоками во всех осях, и вот тогда это можно встраивать в язык. Не в библиотеку, а именно на уровне языка. И тогда код вида {i+=d, j+=getInput();} действительно будет выполняться параллельно. Ну и, естественно, запись вида class CMyUsefulJob :public CThead { будет инструктировать компилятор выносить код данного класса в отдельный поток.
Почему-то все забывают про процессы. Это гораздо более удобный метод организации многозадачной обработки, чем нити. И гораздо более эффективный в реализации в ядре операционной системы. У процессов много достоинств, а единственный недостаток - это сложность переключения контекста виртуальной памяти. Но в нормальных процессорах поддержка уже давным давно сделана на аппаратном уровне через идентификаторы виртуальных адресных пространств. На ненормальных, то есть, производных от x86, проблема решается через хитрые кэши первого уровня.
Вобщем, затраты на переключение контекста процесса по сравнению с контекстом нити в худшем случае составляют +200 тактов. При этом, затраты на синхронизацию при программировании с нитями и усложнение основных служб ядра операционной системы эти 200 тактов с лихвой перекрывают.
Процессы снимают проблему со стеками и со сборкой мусора, вполне естественным образом: стеки различны, а при завершении процесса все занимаемые ресурсы можно освободить.
Сложность в параллельном программировании упирается не в создание или управление задачами (нитями или процессами), а в сложность описания взаимодействия между ними. Собственно, кажется, в данный момент известно, от куда у этого усложнения по сравнению с обычным программированием ноги растут и работы по исправлению ситуации ведуться. Уточнять не буду, пока статью не опубликую, но желающие могут посмотреть в направлении Linda.
Вобщем, затраты на переключение контекста процесса по сравнению с контекстом нити в худшем случае составляют +200 тактов. При этом, затраты на синхронизацию при программировании с нитями и усложнение основных служб ядра операционной системы эти 200 тактов с лихвой перекрывают.
Процессы снимают проблему со стеками и со сборкой мусора, вполне естественным образом: стеки различны, а при завершении процесса все занимаемые ресурсы можно освободить.
Сложность в параллельном программировании упирается не в создание или управление задачами (нитями или процессами), а в сложность описания взаимодействия между ними. Собственно, кажется, в данный момент известно, от куда у этого усложнения по сравнению с обычным программированием ноги растут и работы по исправлению ситуации ведуться. Уточнять не буду, пока статью не опубликую, но желающие могут посмотреть в направлении Linda.
Процессы снимают проблему со стеками и со сборкой мусора, вполне естественным образом: стеки различны, а при завершении процесса все занимаемые ресурсы можно освободить. - quite right, but: Q: что такое "процесс" в современных осях? A: "Процесс есть субъект владения... Процесс владеет памятью, дескрипторами файлов, цепочками, загруженными модулями..." (Мэт Питрек) В современных осях на х86 процесс - объект сугубо высокоуровневый (ибо аппаратно такого понятия нет) и инкапсулирует в себе всю сущность логически (человеком) выделяемой прикладной задачи.
Если в современных осях распаралеливать на уровне процессов, то нужно организовывать межпроцессное взаимодействие. Если дорастить и окультурить этот механизм, то "процессы" становятся нитями, нити "поднитями" и т.п. И так бесконечно.
Как ни назови поток - суть его одна. Поток - это фрагмент кода, выполняющийся параллельно с себеподобными в контексте одной прикладной задачи. Вот что IMHO есть поток для прикладника. И ему, если чесно, насрать на количество ядер и наноразмеры.
На ненормальных, то есть, производных от x86, проблема решается через хитрые кэши первого уровня.
Вроде бы все здесь согласны, что современная аппаратная база от Intel'а не в состоянии путёво реализовать эту задачу. Програмное распараллеливание при наличии многих аппаратных ядер IMHO есть латание дыр и атавизм. Это скоро (надеюсь) уйдет.
Если в современных осях распаралеливать на уровне процессов, то нужно организовывать межпроцессное взаимодействие. Если дорастить и окультурить этот механизм, то "процессы" становятся нитями, нити "поднитями" и т.п. И так бесконечно.
Как ни назови поток - суть его одна. Поток - это фрагмент кода, выполняющийся параллельно с себеподобными в контексте одной прикладной задачи. Вот что IMHO есть поток для прикладника. И ему, если чесно, насрать на количество ядер и наноразмеры.
На ненормальных, то есть, производных от x86, проблема решается через хитрые кэши первого уровня.
Вроде бы все здесь согласны, что современная аппаратная база от Intel'а не в состоянии путёво реализовать эту задачу. Програмное распараллеливание при наличии многих аппаратных ядер IMHO есть латание дыр и атавизм. Это скоро (надеюсь) уйдет.
Существуют различные современные ОС. И в них процессами называется разное.
И вопрос: а чем поддержка виртуальной памяти, например, не является аппаратной поддержкой процессов? Собственно, для процесса больше ничего и не нужно от аппаратуры. Остальное абстрагирование - это уже задача операционной системы. И прикладник видит именно то, что даёт ему ОС, а не то, что даёт ему железо.
Кроме того, Вы ошибаетесь насчёт понятия нити и задачи. Потому что для вычисления одного кода недостаточно, нужны данные, нужен процессор, нужна память, etc. И для прикладника (правильного прикладника) нить - это более или менее независимая задача от других задач (о параллельности речь может и не идти совсем). При этом, независимость может быть очень разная. Апогей независимости - это процесс, поэтому он никак не может стать нитью, или поднитью, или подподнитью. Наоборот, развязка нитей приблежает их к процессам и даёт возможность, например, приложению работать на нескольких компьютерах. Разделение адресных пространств - это благо.
И програмное распараллеливание никуда не уйдёт. Возможно, оно будет производиться автоматически, но уж точно программным способом. Все современные архитектуры: Cell, VLIW, EDGE, multicell - это упрощение железа за счёт добавления мозгов компилятору и операционной системе.
И вопрос: а чем поддержка виртуальной памяти, например, не является аппаратной поддержкой процессов? Собственно, для процесса больше ничего и не нужно от аппаратуры. Остальное абстрагирование - это уже задача операционной системы. И прикладник видит именно то, что даёт ему ОС, а не то, что даёт ему железо.
Кроме того, Вы ошибаетесь насчёт понятия нити и задачи. Потому что для вычисления одного кода недостаточно, нужны данные, нужен процессор, нужна память, etc. И для прикладника (правильного прикладника) нить - это более или менее независимая задача от других задач (о параллельности речь может и не идти совсем). При этом, независимость может быть очень разная. Апогей независимости - это процесс, поэтому он никак не может стать нитью, или поднитью, или подподнитью. Наоборот, развязка нитей приблежает их к процессам и даёт возможность, например, приложению работать на нескольких компьютерах. Разделение адресных пространств - это благо.
И програмное распараллеливание никуда не уйдёт. Возможно, оно будет производиться автоматически, но уж точно программным способом. Все современные архитектуры: Cell, VLIW, EDGE, multicell - это упрощение железа за счёт добавления мозгов компилятору и операционной системе.
Сложность в параллельном программировании упирается не в создание или управление задачами (нитями или процессами), а в сложность описания взаимодействия между ними.
Вот как раз это и сложнее в процессах чем в потоках.
Неа. Это только кажется, что в потоках это проще. Общая память с синхронизацией через разнообразные lock'и и события, обычно выходит логически более сложной, чем простой pipe между двумя процессами. К этому можно добавить необходимость считать ссылки, следить за буфферами памяти, развешивая на них конечные автоматы, и так далее.
Общемировой опыт, изложенный, например, в taoup, говорит о том, что это как раз правильные нити превращаются в нечто подобное процессам: взаимодействие через очереди сообщений (аналог pipe'ов или socket'ов) и явная привязка нитей к обрабатываемым общим данным (аналог mmap). Мой собственный опыт разработки чего-то более или менее надёжного и эффективного это подтверждает.
Общемировой опыт, изложенный, например, в taoup, говорит о том, что это как раз правильные нити превращаются в нечто подобное процессам: взаимодействие через очереди сообщений (аналог pipe'ов или socket'ов) и явная привязка нитей к обрабатываемым общим данным (аналог mmap). Мой собственный опыт разработки чего-то более или менее надёжного и эффективного это подтверждает.
Общая память с синхронизацией через разнообразные lock'и и события, обычно выходит логически более сложной, чем простой pipe между двумя процессами.
Зависит от задачи. В некоторых задачах да.
Вообщем есть 2 основных направления обеспечения взаимодействия между потоками или процессами:
1. data sharing (для разных процессов он тоже возможен и будет реализован через shared memory + межпроцессорные блокировки)
2. message passing
Смысл моего топика в том что-бы оградить высокоуровневого программиста и от обеих типов низкоуровневых стратегий синхронизации. Программиста в идеале не должно волновать как именно будет опеспечиваться парралелизм, за счёт потоков или за счёт процессов. И как именно обеспечивается синхронизация.
1. data sharing (для разных процессов он тоже возможен и будет реализован через shared memory + межпроцессорные блокировки)
2. message passing
Смысл моего топика в том что-бы оградить высокоуровневого программиста и от обеих типов низкоуровневых стратегий синхронизации. Программиста в идеале не должно волновать как именно будет опеспечиваться парралелизм, за счёт потоков или за счёт процессов. И как именно обеспечивается синхронизация.
Угу. К этому и нужно стремиться. Мне просто хотелось напомнить, что существуют и процессы на современном этапе.
А что до избавления программистов от низкоуровневых подробностей, то это уже делается с различной степенью корявости. T-Система, OpenMP, Cilk, Glasgow Parallel Haskell, Parallel Prolog, Distributed Parallel Object Manager for Smalltalk. Вобщем, на любой вкус.
IMHO, общественности обратить на это всё богатство форм и размеров мешает только агрессивная пропаганда .Net и Intel C/C++.
А что до избавления программистов от низкоуровневых подробностей, то это уже делается с различной степенью корявости. T-Система, OpenMP, Cilk, Glasgow Parallel Haskell, Parallel Prolog, Distributed Parallel Object Manager for Smalltalk. Вобщем, на любой вкус.
IMHO, общественности обратить на это всё богатство форм и размеров мешает только агрессивная пропаганда .Net и Intel C/C++.
Да и P.S. очередной: многие современные компиляторы, даже gcc с недавних пор поддерживают автоматическое распараллеливание программ. Копать в сторону OpenMP.
Есть же QT - от trolltech.com
Есть понятие сигналы и слоты. У многопоточности нет проблем. Есть другие проблемы. Как к примеру линейные ресурсоемкие алгоритмы (поиск, обход n-дерева, построение бинарного дерева, архивация, и др.) переложить на многопоточность.
Есть понятие сигналы и слоты. У многопоточности нет проблем. Есть другие проблемы. Как к примеру линейные ресурсоемкие алгоритмы (поиск, обход n-дерева, построение бинарного дерева, архивация, и др.) переложить на многопоточность.
>Почему-то все забывают про процессы. Это гораздо более удобный метод
>организации многозадачной обработки, чем нити. И гораздо более
>эффективный в реализации в ядре операционной системы. У процессов много
>достоинств, а единственный недостаток - это сложность переключения
>контекста виртуальной памяти. Но в нормальных процессорах поддержка уже
>давным давно сделана на аппаратном уровне через идентификаторы
>виртуальных адресных пространств. На ненормальных, то есть, производных
>от x86, проблема решается через хитрые кэши первого уровня.
Бред вы полный написали. Процессы не исполняются. Процесс - среда для потоков. Процесс жив до тех пор пока в нем есть хотя бы один поток. Не надо забывать, что контест процесса удовольствие дорогое, намного более дорогое чем контекст потока.
>Процессы снимают проблему со стеками и со сборкой мусора, вполне
>естественным образом: стеки различны, а при завершении процесса все
>занимаемые ресурсы можно освободить.
Чего за бред про стеки? У каждого потока свой стек (под виндой даже 2). С этим проблем никаких нет.
Товарищи! Ну кто вам сказал, что в современных ЯВУ нет средств неявного обращения с потоками? Для примера возьмем C#. Вводится понятие пула потоков. Для каждого процесса создается пул рабочих потоков. Причем обращение к ним происходит неявно, посредством вызова Delegate.BeginInvoke/EndInvoke. Подробней читаем тут:
http://www.codeproject.com/csharp/AsyncMethodInvocation.asp
Такая концепция коренным образом отлична от классической. В классической модели программист явно указывает набор комманд, и поток в котором этот набор должен выполняться. Такой подход противоречит самой идее масштабируемости приложения под любое число ядер. Напротив, в концепции с пулом потоков, заранее не предопределено в каком потоке будет выполняться та, или иная подпрограмма. Есть один или несколько "главных" потоков, которые раздают некоторому множеству "рабочих" потоков очереди заявок на выполнение операций. Такой подход хорош во всем. Скажем если ядра в процессоре 2, то нет смысла держать больше 2х рабочих потоков. А если 16, то есть и еще какой.
Теперь про классический Win32 и C++. В самом языке С++ нет встроенных конструкций организации пула потоков. Однако WinAPI предоставляют подмножество функций user-mode APC (Asynchronous Procedure Calling) для задания очереди асинронных операций для потока. Используя APC, можно создать пул потоков без каких либо затруднений. Именно на этой концепции и держится часть механизма обработки прерываний - DPC - суть тот же APC, толко режима ядра и при повышенном IRQL.
Однако никакие концепции и абстракции не решат проблему синхронизации доступа к ресурсам и исключения взаимоблокировок. Конечно можно разработать общий способ, как например в C# ключевое слово lock(...). Однако всё равно компилятор никогда сам не определит точные блоки кода, на которые надо ставить блокировку, т.е. критические секции сам не расставит. Это оочень интеллектуальная задача. Можно конечно лочить всё подрад, но производительность в таком случае упадет капитально. Всё равно синхронизацию должен будет определять программист.
>организации многозадачной обработки, чем нити. И гораздо более
>эффективный в реализации в ядре операционной системы. У процессов много
>достоинств, а единственный недостаток - это сложность переключения
>контекста виртуальной памяти. Но в нормальных процессорах поддержка уже
>давным давно сделана на аппаратном уровне через идентификаторы
>виртуальных адресных пространств. На ненормальных, то есть, производных
>от x86, проблема решается через хитрые кэши первого уровня.
Бред вы полный написали. Процессы не исполняются. Процесс - среда для потоков. Процесс жив до тех пор пока в нем есть хотя бы один поток. Не надо забывать, что контест процесса удовольствие дорогое, намного более дорогое чем контекст потока.
>Процессы снимают проблему со стеками и со сборкой мусора, вполне
>естественным образом: стеки различны, а при завершении процесса все
>занимаемые ресурсы можно освободить.
Чего за бред про стеки? У каждого потока свой стек (под виндой даже 2). С этим проблем никаких нет.
Товарищи! Ну кто вам сказал, что в современных ЯВУ нет средств неявного обращения с потоками? Для примера возьмем C#. Вводится понятие пула потоков. Для каждого процесса создается пул рабочих потоков. Причем обращение к ним происходит неявно, посредством вызова Delegate.BeginInvoke/EndInvoke. Подробней читаем тут:
http://www.codeproject.com/csharp/AsyncMethodInvocation.asp
Такая концепция коренным образом отлична от классической. В классической модели программист явно указывает набор комманд, и поток в котором этот набор должен выполняться. Такой подход противоречит самой идее масштабируемости приложения под любое число ядер. Напротив, в концепции с пулом потоков, заранее не предопределено в каком потоке будет выполняться та, или иная подпрограмма. Есть один или несколько "главных" потоков, которые раздают некоторому множеству "рабочих" потоков очереди заявок на выполнение операций. Такой подход хорош во всем. Скажем если ядра в процессоре 2, то нет смысла держать больше 2х рабочих потоков. А если 16, то есть и еще какой.
Теперь про классический Win32 и C++. В самом языке С++ нет встроенных конструкций организации пула потоков. Однако WinAPI предоставляют подмножество функций user-mode APC (Asynchronous Procedure Calling) для задания очереди асинронных операций для потока. Используя APC, можно создать пул потоков без каких либо затруднений. Именно на этой концепции и держится часть механизма обработки прерываний - DPC - суть тот же APC, толко режима ядра и при повышенном IRQL.
Однако никакие концепции и абстракции не решат проблему синхронизации доступа к ресурсам и исключения взаимоблокировок. Конечно можно разработать общий способ, как например в C# ключевое слово lock(...). Однако всё равно компилятор никогда сам не определит точные блоки кода, на которые надо ставить блокировку, т.е. критические секции сам не расставит. Это оочень интеллектуальная задача. Можно конечно лочить всё подрад, но производительность в таком случае упадет капитально. Всё равно синхронизацию должен будет определять программист.
Однако никакие концепции и абстракции не решат проблему синхронизации доступа к ресурсам и исключения взаимоблокировок. Конечно можно разработать общий способ, как например в C# ключевое слово lock(...). Однако всё равно компилятор никогда сам не определит точные блоки кода, на которые надо ставить блокировку, т.е. критические секции сам не расставит. Это оочень интеллектуальная задача.
Проблема в том что для решения этой задачи нужна информация обо всех зависимостях в системе, и у программиста какраз такой информации нету, а у компилятора\виртуальной машины есть. Более того, такие зависимости могут появляться во время выполнения, и виртуальная машина сможет разрешать такие ситуации.
Поэтому эту задачу должен решать не программист, а именно виртуальная машина.
Бред вы полный написали. Процессы не исполняются. Процесс - среда для потоков. Процесс жив до тех пор пока в нем есть хотя бы один поток. Не надо забывать, что контест процесса удовольствие дорогое, намного более дорогое чем контекст потока.
Скажите это разработчикам Plan9 или FreeBSD. Windows is not the only operating system. А мир гораздо богаче, чем нам всем тут кажется. Кроме того, Вы сами можете попробовать написать, например, mutex для многоядерного процессора и убедиться в том, что нити - это не такое уж дешёвое удовольствие.
Чего за бред про стеки? У каждого потока свой стек (под виндой даже 2). С этим проблем никаких нет.
Угу. А это вы скажите всем тем, кто случайно переписывал содержимое стека одной нити из другой, а потом неделю вылавливал ошибку.
Однако никакие концепции и абстракции не решат проблему синхронизации доступа к ресурсам и исключения взаимоблокировок...
Можно конечно лочить всё подрад, но производительность в таком случае упадет капитально. Всё равно синхронизацию должен будет определять программист.
Неа. Существуют языки, программы на которых можно выполнять параллельно и с синхронизацией без явных на то указаний программиста.
Скажите это разработчикам Plan9 или FreeBSD. Windows is not the only operating system. А мир гораздо богаче, чем нам всем тут кажется. Кроме того, Вы сами можете попробовать написать, например, mutex для многоядерного процессора и убедиться в том, что нити - это не такое уж дешёвое удовольствие.
Чего за бред про стеки? У каждого потока свой стек (под виндой даже 2). С этим проблем никаких нет.
Угу. А это вы скажите всем тем, кто случайно переписывал содержимое стека одной нити из другой, а потом неделю вылавливал ошибку.
Однако никакие концепции и абстракции не решат проблему синхронизации доступа к ресурсам и исключения взаимоблокировок...
Можно конечно лочить всё подрад, но производительность в таком случае упадет капитально. Всё равно синхронизацию должен будет определять программист.
Неа. Существуют языки, программы на которых можно выполнять параллельно и с синхронизацией без явных на то указаний программиста.
Проблема многопоточности надуманная.
Могу доказать. Для тех кто в Windows,
жмем cntr+alt+del запускается Task Manager
Вид->Выбрать столбцы-> (ставим галку счетчик потоков)
И смотрим.
firefox.exe - 15 потоков
httpd.exe - 252 потоков :)
miranda32.exe - 8 потоков
и т.д.
Проблемы написания многопоточных приложений нет!
Есть проблема модификации линейных алгоритмов, с учетом n-поточности.
Могу доказать. Для тех кто в Windows,
жмем cntr+alt+del запускается Task Manager
Вид->Выбрать столбцы-> (ставим галку счетчик потоков)
И смотрим.
firefox.exe - 15 потоков
httpd.exe - 252 потоков :)
miranda32.exe - 8 потоков
и т.д.
Проблемы написания многопоточных приложений нет!
Есть проблема модификации линейных алгоритмов, с учетом n-поточности.
OpenMP давно уже позволяет автоматом творить всё в потоках путём меток а-ля "вот тут можно многопоточно", "а тут многопоточно нельзя". Он не столь идеален как ручной способ но куда более быстрый в осуществлении.
diablitozz, проблемы многопоточности как явления нету, конечно. Есть проблема что программы создавать с поддержкой многопоточности не в пример сложнее чем линейные. И даже дело не в самом написании, а в проблемах которые возникают потом абсолютно внезапно в каком-то одном конкретном случае. Проблема может и через год возникнуть.
Кстати говоря забавно. Попробовал потоки в питоне на 8-ядерном сервере. Удалось выжать максимум 250% из 800%. В то время как на си с pthreads четко 800% при 8 потоках :)). Ещё интересно что в питоне (да будь проклят этот gil) потоки переключаются сначала операционкой, потом ещё и самим питоном... а в си - при создании потока он буквально "вешается" на 1 ядро.т.е. 7 потоков там сжирают ровно 7 ядер из 8, одно пустует (естественно, они меняются), а в питоне получается что все ядра пыхтят но не на полную катушку.
Надо бы ещё с erlang поэкспериментировать...
diablitozz, проблемы многопоточности как явления нету, конечно. Есть проблема что программы создавать с поддержкой многопоточности не в пример сложнее чем линейные. И даже дело не в самом написании, а в проблемах которые возникают потом абсолютно внезапно в каком-то одном конкретном случае. Проблема может и через год возникнуть.
Кстати говоря забавно. Попробовал потоки в питоне на 8-ядерном сервере. Удалось выжать максимум 250% из 800%. В то время как на си с pthreads четко 800% при 8 потоках :)). Ещё интересно что в питоне (да будь проклят этот gil) потоки переключаются сначала операционкой, потом ещё и самим питоном... а в си - при создании потока он буквально "вешается" на 1 ядро.т.е. 7 потоков там сжирают ровно 7 ядер из 8, одно пустует (естественно, они меняются), а в питоне получается что все ядра пыхтят но не на полную катушку.
Надо бы ещё с erlang поэкспериментировать...
На счёт OpenMP всё равно это получается низкоуровневая синхронизация. Надо самому сидеть и смотреть где можно много потоков пускать а где нет.
Моя идея в том, что от низкоуровневых примитивов надо отказаться польностью оставив их виртуальной машине.
Думаю что в существующих ОС напрямую от потоков отказаться не выйдет. Для этого нужно целиком менять всю концепцию ОС. И фреймворком тут не отделаешься... Нужно делать .NET OS.
Я и не говорю что надо отказываться от потоков. А тем более в ОС. Я говорю что не надо потоками и синхронизацией напрягать высокоуровневых программистов.
А по другому не выйдет. Либо ядро ОС видит весь граф принадлежности обьектов потокам и зависимостей, либо этим занимается программист...
3. либо этим занимается виртуальная машина
4. либо этим занимается фреймворк.
:)
4. либо этим занимается фреймворк.
:)
Виртуаьная машина не прокатит. Сейчас в винде и так введена концепция виртуализации устройств. От дедлоков это не спасает.
Фреймворк этим заниматься не может в принципе без большущего и сложненного драйвера режимя ядра, который бы перехватывал и редиспетчеризировал все системные вызовы обращений к обьектам ядра и строил бы граф зависимостей по потокам, да еще и управлял бы им. Еще нужно не забывать про вытесняющую многозадачность. При том бы 50% процессорного времени уходило бы на работу этого драйвера. Т.к. фактически любая операция ввода-вывода сопряжена с некоторым объектом ядра...
Фреймворк этим заниматься не может в принципе без большущего и сложненного драйвера режимя ядра, который бы перехватывал и редиспетчеризировал все системные вызовы обращений к обьектам ядра и строил бы граф зависимостей по потокам, да еще и управлял бы им. Еще нужно не забывать про вытесняющую многозадачность. При том бы 50% процессорного времени уходило бы на работу этого драйвера. Т.к. фактически любая операция ввода-вывода сопряжена с некоторым объектом ядра...
Самая красивая реализация потоков мне кажется в QT
Сигналы и слоты очень удобны. Поэтому всякие C# и JAVA даже не рассматриваются как средства разработки :)
http://doc.trolltech.com/4.3/threads.html
Очень просто и синхронизация, с помощью сигналов и слотов удобна.
Есть проблемы в компиляторах или в операционных системах.
Но в GCC и Linux таких проблем нет.
Надеюсь, что и в Windows Vista тоже проблем не предвидится
Сигналы и слоты очень удобны. Поэтому всякие C# и JAVA даже не рассматриваются как средства разработки :)
http://doc.trolltech.com/4.3/threads.html
Очень просто и синхронизация, с помощью сигналов и слотов удобна.
Есть проблемы в компиляторах или в операционных системах.
Но в GCC и Linux таких проблем нет.
Надеюсь, что и в Windows Vista тоже проблем не предвидится
Я правильно понимаю что сигналы и слоды в QT это разновидность message passing-а? Т.е. опять таки низкоуровневые примитивы синхронизации?
ну тут не совсем так. QT работает так. Вы пишите код на C++, с использованием макрокоманд. В процессе компиляции макросы заменяются, на строчки кода, потом создается объектная модель obj. Идёт соединение сигналов и слотов на уровне obj файла. Потом компилится выполняемый код. Тоесть синхронизация идёт на уровне выполняемого кода. А не на уровне библиотек. Как к примеру CORBA или .NET Remoting
UFO just landed and posted this here
кажется у автора есть единомышленники :)
Multiprocessor C# 4.0
http://u-pereslavl.botik.ru/~vadim/MCSha…
Multiprocessor C# 4.0
http://u-pereslavl.botik.ru/~vadim/MCSha…
оно конечно не на уровне системы, но чтото общее имеется :)
Т.е. новая технология должна автоматически распараллеливать определённым образом написанные высокоуровневые программы. Кстати, я считаю, что информации о зависимостях между объектами достаточно не только для сборки мусора, но и для такого автоматического распараллеливания.
великолепная статья, и великолепные коментарии! Спасибо Господа!
Всё будет ништяк!
То, что сейчас считается проблемой, завтра будет вызывать смех. Умели же 60 лет назад заставить считать 18000 ламп! А вы тут про 2-4-8 ядер :) Писали же программы без клавиатуры и мониторов! Интернет появился до Виндовс - и работали люди! Так что не переживайте - Intel не оставит нас наедине со своими процессорами, иначе их покупать никто не будет.
То, что сейчас считается проблемой, завтра будет вызывать смех. Умели же 60 лет назад заставить считать 18000 ламп! А вы тут про 2-4-8 ядер :) Писали же программы без клавиатуры и мониторов! Интернет появился до Виндовс - и работали люди! Так что не переживайте - Intel не оставит нас наедине со своими процессорами, иначе их покупать никто не будет.
Кстати, вопрос-задача для гуру ПП: есть ли такие решения для "широких масс", чтобы скажем, плеер работал на одном ядре, запись диска на другом, браузер на третьем, процессы винды на четвёртом, сервера на пятом...?
Как думаете, имеет ли право на существование такой способ распараллеливания? Какие его достоинстваи недостатки? ИМХО, для обычного пользователя вариант самый классный. Ведь зачем обычному пользователю полноценные реализации ПП?
Как думаете, имеет ли право на существование такой способ распараллеливания? Какие его достоинстваи недостатки? ИМХО, для обычного пользователя вариант самый классный. Ведь зачем обычному пользователю полноценные реализации ПП?
В 2000-2004 годах была успешно проведена суперкомпьютерная программа "СКИФ" Союзного государства России и Беларуси. Целью программы была разработка отечественных суперкомпьютеров, а также программного обеспечения для них. В результате было разработано семейство суперкомпьютеров, два из которых (СКИФ-К500 и СКИФ-К1000) попали в список 500 самых мощных суперкомпьютеров мира (см. top500.org).
Было разработано ПО для этих машин, в том числе система параллельного программирования OpenTS (Open T-System). Она, кроме всего прочего, позволяет создавать приложения, которые не требуют пересборки и отлично работают на разных аппаратных платформах: multi-core, cluster, SMP, GRID.
Система является надстройкой над C++ и предоставляет среду исполнения для языка Т++.
Он является семантически "гладким" расширением C++ и сочетает в себе функциональную и императивную семантику.
В настоящее время система активно развивается.
Ссылки:
1) Сайт "СКИФ"-а:
http://skif.pereslavl.ru
2) Публикации про "СКИФ" и OpenTS:
http://skif.pereslavl.ru/skif/index.cgi?module=chap&action=getpage&data=publications\publications.html&chap=menu_rezultaty.html
Было разработано ПО для этих машин, в том числе система параллельного программирования OpenTS (Open T-System). Она, кроме всего прочего, позволяет создавать приложения, которые не требуют пересборки и отлично работают на разных аппаратных платформах: multi-core, cluster, SMP, GRID.
Система является надстройкой над C++ и предоставляет среду исполнения для языка Т++.
Он является семантически "гладким" расширением C++ и сочетает в себе функциональную и императивную семантику.
В настоящее время система активно развивается.
Ссылки:
1) Сайт "СКИФ"-а:
http://skif.pereslavl.ru
2) Публикации про "СКИФ" и OpenTS:
http://skif.pereslavl.ru/skif/index.cgi?module=chap&action=getpage&data=publications\publications.html&chap=menu_rezultaty.html
UFO just landed and posted this here
Sign up to leave a comment.
Какой должна быть будущая технология параллельного программирования