Как оптимизировать работу с двумя, четырьмя и более старыми мультипроцессорами? - PullRequest
11 голосов
/ 26 декабря 2011

Ребята, я программирую высокоскоростное программное обеспечение более 20 лет и знаю практически все хитрости в книге: создание микропланшетов, создание профилей, многозадачность в пользовательском режиме, хвостовая рекурсия.Linux, Windows и многое другое.

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

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

Ясно, что между ядрами существует "скрытое взаимодействие", которое не очевидно из моего собственного программного кода.Я слышал о кеше L1 и других проблемах, но они для меня непрозрачны.

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

Любые советы или отличные сайты или книги?После долгих поисков я выхожу пустым.

С уважением, Уэйн

Ответы [ 6 ]

4 голосов
/ 26 декабря 2011

мой собственный вопрос с ответом на родственном сайте stackoverflow: https://softwareengineering.stackexchange.com/questions/126986/where-can-i-find-an-overview-of-known-multithreading-design-patterns/126993#126993

Я скопирую ответ, чтобы избежать необходимости переходов по ссылкам:

Цитата Борис:

Параллельное программирование в Microsoft .NET: шаблоны проектирования для декомпозиции и координации на многоядерных архитектурах https://rads.stackoverflow.com/amzn/click/0735651590

Это книга, которую я всем сердцем рекомендую.

Это:

Новое - опубликовано в прошлом году.Означает, что вы не читаете несколько устаревших практик.

Коротко - около 200+ страниц, насыщенных информацией.В наши дни слишком много для чтения и слишком мало времени для чтения книг на 1000 страниц.

Легко читается - он не только очень хорошо написан, но и вводит понятия, которые трудно понять, действительно простым для чтения способом.

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

Кроме того, если вы хотите узнать больше о деталях низкого уровня, это лучший ресурс, который я нашел: " Искусствомногопроцессорного программирования"Он написан с использованием java в качестве примеров кода, что хорошо сочетается с моим фоном C #.

PS: у меня около 5 лет опыта" параллельного программирования "на ядре" (с помощью C #)так что надеюсь, что вы можете доверять мне, когда я говорю, что " Искусство многопроцессорного программирования " качает

4 голосов
/ 26 декабря 2011

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

http://www.amazon.com/Computer-Architecture-Quantitative-Approach-4th/dp/0123704901

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

2 голосов
/ 29 декабря 2011

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

http://msdn.microsoft.com/en-us/magazine/cc872851.aspx

http://www.codeproject.com/KB/threads/FalseSharing.aspx

Rgds GJ

2 голосов
/ 26 декабря 2011
1 голос
/ 13 февраля 2012

Существуют различные аспекты многопоточности, требующие разных подходов.

Например, на веб-сервере широко используется использование потоковых пулов, поскольку оно предположительно "хорошо" для производительности.Такие пулы могут содержать сотни потоков, ожидающих запуска.Использование такого количества потоков приведет к тому, что планировщик будет работать сверхурочно, что отрицательно сказывается на производительности, но его нельзя избежать в системах Linux.Для Windows предпочтительным методом является механизм IOCP, который рекомендует количество потоков, не превышающее количество установленных ядер.Это приводит к тому, что приложение становится (завершение ввода / вывода) управляемым событием, что означает, что при опросе не теряются циклы.Несколько задействованных потоков сводят работу планировщика до минимума.

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

  • , приспосабливая код к минимальному объему памяти (= помещается в кэш кода) и не вызывая другие функции или переходыповсюду.
  • настройка чтения и записи памяти до минимального размера.
  • информирование механизма предварительной выборки предстоящих операций чтения из ОЗУ.
  • настройка работы таким образом, чтобы отношениеРабота, выполняемая внутри собственных кешей ядра (L1 и L2), настолько велика, насколько это возможно, по сравнению с работой вне их (L3 и RAM).

Чтобы выразить это иначе: соответствовать применимому кодуи данные разбиваются на как можно меньшее количество строк кэша (по 64 байта каждая), потому что в конечном итоге именно это будет определять масштабируемость.Если система кэш / память способна выполнять x операций со строками кэша каждую секунду, ваш код будет работать быстрее, если его требования составляют пять строк кэша на единицу работы (=> x / 5), а не одиннадцать (x / 11) или пятьдесят два(x / 52).

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

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

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

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

0 голосов
/ 31 декабря 2011

Я нашел эту ссылку, которая конкретно объясняет проблемы обработка многоядерного кэша на процессорах, которые влияли на многопоточная программа.

http://www.multicoreinfo.com/research/intel/mem-issues.pdf

На сайте multicoreinfo.com вообще много хорошего информация и ссылки о многоядерном программировании.

...