Многоядерное программирование: сложные части - PullRequest
14 голосов
/ 05 июня 2010

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

Ответы [ 7 ]

7 голосов
/ 05 июня 2010

Что такое полезная единица работы для распараллеливания, и как мне ее найти / организовать?

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

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

Можно также рассмотреть обсуждение нотации big-Oh и ее приложений. Мы все надеемся, что примитивы параллелизма стоят O (1). Если это так, то если вы найдете работу со стоимостью O (x)> O (1), то эта работа является хорошим кандидатом для распараллеливания. Если ваша предложенная работа также является O (1), то, будет ли она эффективной или нет, зависит от постоянных факторов, и мы вернемся к калибровке, как указано выше.

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

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

6 голосов
/ 05 июня 2010

Я думаю, что отчасти это зависит от того, насколько базова или продвинута книга / аудитория. Когда вы переходите от однопоточного к многопоточному программированию в первый раз, вы обычно падаете с огромного обрыва (и многие никогда не приходят в себя, см., Например, все запутанные вопросы о Control.Invoke).

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

  • Измерение : решить, какую метрику вы хотите улучшить, правильно ее измерить (так легко случайно измерить неправильную вещь), используя правильные инструменты, различая сигнал и шум, интерпретируя результаты и понимание, почему они такие, какие они есть.

  • Тестирование : как написать тесты, которые допускают несущественное недетерминизм / чередование, но при этом определяют правильное поведение программы.

  • Отладка : инструменты, стратегии, когда «трудно отлаживать» подразумевает обратную связь для улучшения вашего кода / дизайна и улучшения состояния изменяемого раздела и т. Д.

  • Физическое и логическое Сходство с потоком : понимание потока GUI, понимание того, как, например, MailboxProcessor / агент F # может инкапсулировать изменяемое состояние и работать в нескольких потоках, но всегда только с одним логическим потоком (один программный счетчик).

  • Шаблоны (и когда они применяются): объединение, уменьшение карты, производитель-потребитель, ...

Я ожидаю, что, например, будет большая аудитория. «помогите, у меня есть однопоточное приложение с 12% загрузкой ЦП, и я хочу изучить его достаточно, чтобы оно работало в 4 раза быстрее без особой работы» и, к примеру, меньшую аудиторию. «Мое приложение масштабируется сублинейно, так как мы добавляем ядра, потому что здесь, кажется, есть конфликт, есть ли лучший подход для использования?», и поэтому небольшая проблема может обслуживать каждую из этих аудиторий.

5 голосов
/ 05 июня 2010

Поскольку вы пишете целую книгу по многоядерному программированию в .Net.

Я думаю, что вы также можете немного выйти за рамки многоядерности .

Например, вы можете использовать главу о параллельных вычислениях в распределенной системе в .Net. Маловероятно, что в .Net пока нет зрелых платформ. DryadLinq является ближайшим. (С другой стороны, Hadoop и его друзья на платформе Java действительно хороши.)

Вы также можете использовать главу, демонстрирующую некоторые вычисления на GPU.

4 голосов
/ 12 июня 2010

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

3 голосов
/ 05 июня 2010

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

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

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

2 голосов
/ 05 июня 2010

Это не столько теоретические детали, сколько подробности практической реализации, которые запутывают людей.

Как обстоят дела с неизменяемыми структурами данных?

Все время люди пытаются обновить структуру данных из нескольких потоков, считают это слишком сложным, и кто-то выкрикивает «использовать неизменные структуры данных!», И поэтому наш постоянный кодер пишет это:

ImmutableSet set;

ThreadLoop1()
    foreach(Customer c in dataStore1)
        set = set.Add(ProcessCustomer(c));

ThreadLoop2()
    foreach(Customer c in dataStore2)
        set = set.Add(ProcessCustomer(c));

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

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

Как разделить примерно одинаковое количество работы между потоками?

Правильный шаг - 1018 * трудно . Иногда вы разбиваете один процесс на 10 000 шагов, которые могут выполняться параллельно, но не все шаги занимают одинаковое количество времени. Если вы разделите работу на 4 потока, и первые 3 потока завершатся за 1 секунду, а последний поток займет 60 секунд, ваша многопоточная программа не намного лучше однопоточной версии, верно?

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

Сколько потоков?

Если ваша проблема хорошо распараллеливается, добавление большего количества потоков должно ускорить ее, верно? Ну, не совсем, здесь нужно учитывать много вещей:

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

Так как же вы раскручиваете достаточно потоков, чтобы минимизировать время выполнения?

А если множество других приложений раскручивают потоки и конкурируют за ресурсы, как вы обнаруживаете изменения производительности и автоматически настраиваете программу?

1 голос
/ 19 июня 2010

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

Обычно я нахожу отладку и медведем.

...