Насколько важна многопоточность в современной индустрии программного обеспечения? [закрыто]


59

У меня почти 3 года опыта написания веб-приложений на Java с использованием MVC-фреймворков (например, Struts). До сих пор я никогда не писал многопоточный код, хотя я написал код для крупных розничных сетей.

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


8
Вы, возможно, не сделали этого явно, но вы определенно воспользовались этим за кулисами.
Мартин Йорк,

1
Я слишком редко работаю с многопоточным кодом для работы, но я стараюсь читать его / иметь возможность обсуждать это во время интервью. Я не хотел бы работать с кодерами, которые не получают потоки, и я не хотел бы работать с кодерами, которым все равно, получают ли другие кодеры потоки.
Работа

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

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

1
Способность «мыслить вне потока» очень хороша даже для однопоточного программирования. Вы принимаете намного меньше как должное, и ваш код, как правило, более надежный и многократно используемый.
CorsiKa

Ответы:


92

Это чрезвычайно важно.

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

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

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

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

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

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


5
+1 за отличный ответ, он заслуживает большего уважения, чем моя скромная попытка.
Петер Тёрёк

2
Информация все чаще будет доступна в асинхронном режиме. Если это не правда. , ,
Surfasb

2
concurrencyважнее, чем asynchronous поведение. Вы можете иметь асинхронный без параллелизма (то есть несколько потоков на одном ядре процессора) asynchronousне является семантической заменой concurrency.

5
@Jarrod: Укрощение асинхронность является более важной , чем просто приручить параллелизм именно по той причине , вы упоминаете: параллелизм это просто особенно сложный вид асинхронные. Сложная часть параллелизма - это не «вещи, происходящие в одно и то же время», и, действительно, параллелизм часто является только симулированным параллелизмом , например, некооперативная многозадачность через квантование времени. Сложность заключается в эффективном использовании ресурсов без блокирования, зависания, взаимоблокировки и без выписывания наизнанку программ, которые трудно рассуждать локально.
Эрик Липперт

«параллелизм - это часто только симулируемый параллелизм, например, некооперативная многозадачность с помощью среза времени»: в моем понимании это все еще (истинный) параллелизм, может быть, вы имеете в виду, что это не параллелизм?
Джорджио

46

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


3
+1: важнее, чем когда-либо. Помните также, что при проектировании системы вы также можете получить преимущества многопоточности, просто разделив работу так, чтобы ее выполняло больше процессов.
Скотт С. Уилсон

11
Многие мобильные устройства уже имеют многоядерные процессоры!
Че Джами

3
Я бы сказал, что многопоточность была важна с момента создания первой системы разделения времени. Наличие нескольких процессоров / ядер просто добавляет новое измерение эффективности к наличию нескольких потоков.
jwernerny

Возможно (особенно на мобильных устройствах) темы - плохая идея. Операционная система должна, вероятно, обрабатывать оптимизацию использования ядер без ошибок, пытаясь выполнить многопоточность пользовательского кода. Существует очень мало приложений, в которых обычный пользователь имеет доступ к этой потребности или которые могут быть полезны для множества людей. Единственным исключением являются (высокопроизводительные графические приложения / инструменты для разработчиков / моделирование погоды / веб-серверы (и связанные с ними службы)) - все специализированные приложения очень высокого класса.
Мартин Йорк,

1
@ Tux-D, у вас вполне может быть игра на мобильном устройстве, которая использует более одного ядра. Это не что-то исключительное.
Уайткварк

28

В общем, многопоточность уже достаточно важна, и в ближайшие несколько лет она станет более важной (как отметил Петер Торёк) - именно так процессоры будут масштабироваться в обозримом будущем (больше ядер вместо более высоких МГц) ,

Однако в вашем случае вы работаете в основном с веб-приложениями. Веб-приложения по своей природе являются многопоточными благодаря тому, как ваш веб-сервер обрабатывает запросы для каждого пользователя (то есть параллельно). Хотя для вас, вероятно, важно понимать параллелизм и безопасность потоков (особенно при работе с кэшами и другими общими данными), я сомневаюсь, что вы столкнетесь со слишком многими случаями, когда полезно внутреннее многопоточное выполнение кода веб-приложения (т. Е. Нескольких рабочих). темы по запросу). В этом смысле, я думаю, что быть экспертом в многопоточности не является необходимым для веб-разработчика. Его часто спрашивают в интервью, потому что это довольно сложный вопрос, а также потому, что многие интервьюеры просто задают несколько вопросов за 10 минут до того, как вы туда попадете.


+1 за примечание, что автором постера является веб-разработчик, и большинство контейнеров веб-сервера выполняют приличную работу по многопоточности. Не то чтобы это исключало необходимость в некоторых случаях, но 99% времени многопоточного кода контроллера не является самым большим улучшением производительности для вызова MVC.
Муфаса

19

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

Потоки - это только одна модель и шаблон реализации для реализации concurrentпрограмм.

Например, вы можете написать очень масштабируемое и отказоустойчивое программное обеспечение, не выполняя многопоточность на таких языках, как Erlang.


+1 хотя я все еще думаю, что Erlang многопоточный; сообщество просто переопределило слово «нить», чтобы оно зависело от изменяемого общего состояния и таким образом отличалось от него.
Дэн

1
виртуальная машина Erlang использует по умолчанию 1 поток на каждый процессор, но, как разработчик Erlang, вы не имеете доступа к базовым потокам ОС, только к легким процессам, которые предоставляет виртуальная машина Erlang.

10

Я получаю несколько вопросов о многопоточности во время интервью ...

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


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

6

Понимание того, как использовать многопоточность для повышения производительности, является важнейшим навыком в современной программной среде для большинства отраслей и приложений.

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

Очевидное замечание, что не все приложения или среды смогут воспользоваться этим, применимо, например, во многих встроенных системах. Однако кажется, что процессор Atom (и др.), Похоже, работает над тем, чтобы изменить это (облегченный многоядерный процессор начинает становиться все более распространенным).


4

Похоже, вы уже пишете многопоточный код.

Большинство веб-приложений Java могут обрабатывать несколько запросов одновременно, и они делают это с помощью нескольких потоков.

Поэтому я бы сказал, что важно знать основы хотя бы.


18
<nitpick> очевидно (s) он не пишет многопоточный код, только (однопоточный) код, который выполняется в многопоточной среде. </ nitpick>
Péter Török

2

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


2

Краткий ответ: очень.

Более длинный ответ: Электронные (транзисторные) компьютеры быстро приближаются к физическим пределам технологии. Становится все труднее и труднее выжать больше часов из каждого ядра, одновременно управляя выделением тепла и квантовыми эффектами микроскопических контуров (контуры контуров уже расположены настолько близко друг к другу на современных микросхемах, что эффект, называемый "квантовым туннелированием", может сделать электрон «перепрыгивать дорожки» из одной цепи в другую, не нуждаясь в надлежащих условиях для традиционной электрической дуги); Таким образом, практически все производители микросхем вместо этого сосредоточены на том, чтобы каждая тактовая частота могла делать больше, добавляя больше «исполнительных блоков» в каждый процессор. Затем вместо того, чтобы компьютер делал только одну вещь за такт, он может делать 2, 4 или даже 8. Intel имеет «HyperThreading», который в основном разделяет одно ядро ​​процессора на два логических процессора (с некоторыми ограничениями). Практически все производители помещают как минимум два отдельных ядра ЦП в один чип ЦП, и текущий золотой стандарт для настольных ЦП составляет четыре ядра на чип. Восемь возможно при использовании двух процессорных микросхем, есть серверные материнские платы, предназначенные для «четырехъядерных» четырехъядерных процессоров (16 ЕС плюс дополнительный HT), и в следующем поколении процессоров, вероятно, будет шесть или восемь на чип.

Результатом всего этого является то, что, чтобы в полной мере использовать то, как компьютеры набирают вычислительную мощность, вы должны позволить компьютеру «разделять и покорять» вашу программу. В управляемых языках есть по крайней мере поток GC, который обрабатывает управление памятью отдельно от вашей программы. У некоторых также есть «переходные» потоки, которые обрабатывают взаимодействие COM / OLE (как для защиты управляемой «песочницы», так и для повышения производительности). Помимо этого, однако, вам действительно нужно задуматься о том, как ваша программа может выполнять несколько задач одновременно, и спроектировать свою программу с функциями, разработанными для асинхронной обработки частей программы. Windows и пользователи Windows практически ожидают, что ваша программа будет выполнять длинные сложные задачи в фоновых потоках, которые поддерживают пользовательский интерфейс вашей программы (который запускается в главном потоке программы) "реагирующим" на цикл сообщений Windows. Очевидно, что проблемы, которые имеют распараллеливаемые решения (такие как сортировка), являются естественными кандидатами, но существует конечное число типов проблем, которые выигрывают от распараллеливания.


1

Просто предупреждение о многопоточности: больше потоков не означает лучшую эффективность. Если не управлять должным образом, они могут замедлить работу системы. Актер Scala улучшает многопоточность Java и максимизирует использование системы (упомянул это, поскольку вы Java-разработчик).

РЕДАКТИРОВАТЬ: Вот некоторые вещи, которые следует иметь в виду о недостатках многопоточности:

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

Кроме того, эта ссылка может быть полезна примерно так же.


2
Похоже, это не отвечает на вопрос ОП: - /
Петер Тёрёк

Тем не менее, он дает представление о многопоточности на верхнем (самом) уровне. Что нужно учитывать, прежде чем углубляться в многопоточность.
c0da

@ c0da Stack Exchange не является форумом для обсуждения: ответы должны прямо отвечать на вопрос. Можете ли вы расширить свой ответ, чтобы вернуть его к тому, что ищет спрашивающий?

1

Это заставило меня задуматься, насколько важна многопоточность в текущем отраслевом сценарии?

В критических областях производительности, где производительность не зависит от кода сторонних производителей, выполняющего тяжелую работу, а от нашей собственной, я бы склонялся к рассмотрению вещей в таком порядке важности с точки зрения ЦП (GPU - это символ подстановки, который я выиграл не вдаваться):

  1. Эффективность памяти (например, местность ссылки).
  2. алгоритмический
  3. Многопоточность
  4. SIMD
  5. Другие оптимизации (например, подсказки статического предсказания ветвления)

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

Эффективность памяти

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

Например, если нам нужна структура данных, которая предлагает последовательный доступ по линейному времени и вставки в постоянное время сзади, и ничего более для небольших элементов, наивным выбором здесь будет связанный список. Это без учета эффективности памяти. Когда мы рассматриваем эффективность использования памяти в миксе, мы в конечном итоге выбираем более смежные структуры в этом сценарии, такие как растущие структуры на основе массива или более смежные узлы (например, один хранит 128 элементов в узле), соединенные вместе или, по крайней мере, связанный список, поддерживаемый распределителем пула. Они имеют существенное преимущество, несмотря на одинаковую алгоритмическую сложность. Аналогично, мы часто выбираем быструю сортировку массива вместо сортировки слиянием, несмотря на низкую алгоритмическую сложность просто из-за эффективности памяти.

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

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

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

алгоритмический

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

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

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

Наконец, алгоритмы, как правило, больше относятся к категории «реализации», чем к эффективности памяти. Их часто проще улучшить задним числом, даже с изначально неоптимальным алгоритмом. Например, алгоритм обработки изображений низкого качества часто просто реализуется в одном локальном месте в кодовой базе. Это может быть заменено лучшим позже. Однако, если все алгоритмы обработки изображений привязаны к Pixelинтерфейсу, который имеет неоптимальное представление в памяти, но единственный способ исправить это - изменить способ представления нескольких пикселей (а не одного), то мы часто SOL и придется полностью переписать кодовую базу в сторонуImageинтерфейс. То же самое касается замены алгоритма сортировки - обычно это детали реализации, в то время как полное изменение базового представления сортируемых данных или способа их передачи через сообщения может потребовать перепроектирования интерфейсов.

Многопоточность

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

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

Тем не менее, это становится настолько важным. Хотя это может все еще не всегда превосходить что-то вроде эффективности памяти (которая иногда может сделать вещи в сто раз быстрее), учитывая количество ядер, которые мы имеем сейчас, мы видим все больше и больше ядер. Конечно, даже на 100-ядерных машинах я бы по-прежнему ставил эффективность памяти на первое место в списке, поскольку эффективность потоков без нее вообще невозможна. Программа может использовать сотню потоков на такой машине и все еще работать медленно, не имея эффективного представления памяти и шаблонов доступа (которые будут привязаны к шаблонам блокировки).

SIMD

SIMD также немного неуклюжий, поскольку регистры на самом деле становятся шире, а планы становятся еще шире. Первоначально мы видели 64-битные регистры MMX, за которыми следовали 128-битные регистры XMM, способные к 4 параллельным операциям SPFP. Теперь мы видим 256-битные регистры YMM, способные к 8 параллельно. И уже есть планы для 512-битных регистров, которые позволили бы 16 параллельно.

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

Другое дело, что хотя современные компиляторы обычно не справляются с искусно написанным SIMD-кодом, они легко преодолевают наивные попытки. Они могут улучшиться до такой степени, что нам больше не придется делать это вручную или, по крайней мере, не становясь настолько ручным, чтобы писать встроенные или прямые ассемблерные коды (возможно, просто немного человеческого руководства).

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

Другие оптимизации

Это часто то, что я бы посоветовал нам начать называть «микро» в наши дни, если слово предлагает не только выйти за рамки алгоритмического фокуса, но и внести изменения, которые оказывают минимальное влияние на производительность.

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

Вернуться к многопоточности для производительности

Так или иначе, насколько важна многопоточность в контексте производительности? На моем 4-ядерном компьютере он в идеале может делать вещи примерно в 5 раз быстрее (что я могу получить с помощью гиперпоточности). Это было бы гораздо важнее для моего коллеги, который имеет 32 ядра. И это будет становиться все более важным в ближайшие годы.

Так что это очень важно. Но бесполезно просто набросать кучу потоков на проблему, если эффективность памяти не позволяет экономно использовать блокировки, уменьшать ложное совместное использование и т. Д.

Многопоточность вне производительности

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

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

Когда мы не просто распараллеливаем узкий цикл доступа к массивной структуре данных, многопоточность переходит в действительно жесткую категорию «дизайн», и дизайн всегда превосходит реализацию.

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


0

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


0

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

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


0

Исторически людям приходилось бороться, выполняя многопоточное программирование вручную. Они должны были работать со всеми основными компонентами (потоками, семафорами, мьютексами, замками и т. Д.) Напрямую.

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

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

Цель масштабирования по горизонтали. Добавление большего количества стандартных серверов вместо покупки больших серверов.

Тем не менее, факт остается фактом: очень важно понимать многопоточное программирование. Я был в ситуации, когда кто-то создал состояние гонки и даже не знал, что такое состояние гонки, пока мы не заметили странные ошибки во время тестирования.


-1

У моей машины 8 ядер. В диспетчере задач у меня запущено 60 процессов. Некоторые, например VS, используют до 98 потоков. Outlook использует 26. Я ожидаю, что большая часть моей памяти используется стеками, выделенными для каждого из этих незанятых потоков.

Я лично жду выхода 300-ядерного компьютера, чтобы мне не пришлось ждать ответа Outlook. Конечно, к тому времени Outlook будет использовать 301 потоков.

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

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


Я буду часто что-то бить в фоновом потоке, например, при длительной загрузке БД, но очень редко мне приходится иметь дело с условиями гонки или блокировками и т. Д. (На самом деле, вероятно, никогда)
Аран Малхолланд,
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.