Читать онлайн Разработка масштабируемых программ для многоядерных архитектур бесплатно
Введение
В лабораторном практикуме рассматривается круг вопросов, связанных с основами разработки многопоточных приложений, элементами их инструментированной отладки и тестирования. Целью лабораторного практикума является развитие у студентов-программистов навыков разработки масштабируемых многопоточных программ. Для достижения поставленной цели рассмотрены следующие задачи:
– основы многоядерной архитектуры;
– проектирование многопоточных программ с использованием различных инструментальных средств;
– причины плохой масштабируемости программ;
– теоретическая и практическая оценка ускорения и масштабируемости программ;
– элементы оптимизации.
Для демонстрации влияния пропускной способности шины на плохую масштабируемость программ разработана лабораторная работа № 1, в которой описаны реализация последовательного и многопоточного приложений, демонстрирующих проблему, предварительная и практическая оценки ускорения и масштабируемости, оптимизация программы для повышения доли параллельного кода, а также инструментированный анализ загрузки шины.
Влияние размера пула потоков на масштабируемость программ раскрывается в лабораторной работе № 2, в которой приводятся причины использования пула потоков, математическое описание системы, анализ предполагаемых проблем при оптимизации приложения, теоретическая и практическая оценки ускорения и масштабируемости, даны рекомендации по выбору размера пула и очереди.
В качестве языков программирования, в которых разрабатывались и отлаживались приведенные примеры, выбраны С++ и С#, как мощные современные инструменты создания многопоточных приложений. Все теоретические сведения подкреплены примерами и графиками, которые могут служить базой при разработке полноценного программного обеспечения в данной области.
Отчет по каждой лабораторной работе должен включать титульный лист, постановку задачи, теоретические сведения, иерархическую схему процедур, текст основных процедур, результаты работы и выводы.
1 Предпосылки создания многоядерной архитектуры
Гонка тактовых частот, продолжавшаяся на протяжении многих лет уходит в прошлое, так как развитие физики полупроводников, следствием которого стало увеличение числа логических элементов на единицу площади, подчиняющееся закону Гордона Мура, провоцирует ряд проблем, таких как перегрев и физическое ограничение плотности транзисторов. Проблема перегрева транзисторов в современных процессорах стоит очень остро. Сами транзисторы становятся все меньше, но при этом с ростом тактовой частоты процессора они потребляют больше мощности и выделяют больше тепла. До бесконечности это продолжаться не может, поскольку приводит к быстрому обгоранию соответствующего контакта разъема, нагреву и сколам процессора, разряду батарей питания. Суть проблемы заключается в том, что современные процессоры потребляют такую мощность, что при питании их стабилизаторов от шины +5В ток превосходит разумные пределы (мощность равна произведению тока на напряжение, поэтому, чем ниже напряжение, тем выше ток при той же мощности). По всей видимости, масштабирование процессоров по тактовой частоте оказалось не столь простой задачей, как предполагалось, и потому при сегодняшних технологических нормах производства процессоров и малоэффективных воздушных системах охлаждения добиться линейного масштабирования тактовой частоты процессоров не удаётся.
Таким образом, производители столкнулись с проблемой достижения предела прогнозируемой скорости роста тактовой частоты – небольшого зазора оптимизации исполнения в пределах одного ядра, за которым рост сложности становится неоправдан и для дальнейшего наращивания размеров кэш-памяти процессоров остается лишь небольшой зазор для развития [1]. Осознав, что увеличение прежними темпами тактовых частот процессоров не представляется невозможным, нужно было искать принципиально иные технологии увеличения производительности процессоров. Достигая пределов роста скорости и уровня охлаждения, производители процессоров пришли к одному и тому же решению: объединить в одной микросхеме два процессорных ядра. Поэтому перспективным направлением для дальнейшего развития видится многоядерная и многопотоковая архитектура процессоров.
2 Преимущества многоядерной архитектуры процессоров
Еще несколько лет назад в силу технологических ограничений все многопотоковые процессоры строились на базе одного ядра, и такая многопотоковость была названа «одновременной» – Simultaneous Multi Threading (SMT), но с появлением многоядерных процессоров появился альтернативный тип многопотоковости – Chip Multi Processor (CMP).
Многоядерная архитектура – это архитектура, в составе которой находится один физический процессор, содержащий основные логические узлы нескольких процессоров.
Преимущество такого процессора над одноядерным проявляется, прежде всего, при работе с многопоточными приложениями. Многопоточные задачи работают быстрее на двухядерных процессорах, потому что операционная система может распределять программные потоки отдельно по каждому ядру, в то время как на одноядерных процессорах задачи меняются по мере выполнения, то есть по очереди. Применение этой технологии позволит увеличить производительность процессоров нового поколения и одновременно избежать роста потребления энергии, которое накладывает ограничения на развитие одноядерных процессоров. Поскольку производительность памяти увеличивается медленнее, чем скорость процессоров, то чем выше частота процессора, тем больше потеря производительности при обращении к памяти. Два ядра получаются предпочтительней, чем одно, так как в этом случае легче обеспечить процессор данными для обработки.
Такая архитектура предоставляет одну из возможностей преодоления врожденной слабости современных процессоров – «бутылочного горла» архитектуры фон Неймана в соответствии с рисунком 1.
Рисунок 1 – Демонстрация «узкого горла» архитектуры фон Неймана на примере четырехпроцессорной архитектуры Intel Xeon
Впервые публично об этом недостатке сказал создатель Fortran Джон Бэкус на церемонии вручения ему премии имени Тьюринга в 1977 году: «Что такое компьютер по фон Нейману? Когда 30 лет назад Джон фон Нейман и другие предложили свою оригинальную архитектуру, идея показалась элегантной, практичной и позволяющей упростить решение целого ряда инженерных и программистских задач. И хотя за прошедшее время условия, существовавшие на момент ее публикации радикально изменились, мы отождествляем наши представления о компьютерах с этой старой концепций. В простейшем изложении фон-неймановский компьютер состоит из трех частей: это центральный процессор, память и соединяющий их канал, который служит для обмена данными между CPU и памятью, причем маленькими порциями – по одному слову.
Я предлагаю назвать этот канал «бутылочным горлом фон Неймана». Наверняка должно быть менее примитивное решение, чем перекачивание огромного количества данных через «узкое бутылочное горло». Такой канал не только создает проблему для трафика, но еще и является «интеллектуальным бутылочным горлом», которое навязывает программистам «пословное» мышление, не позволяя рассуждать в более высоких концептуальных категориях» [1].
С момента произнесения Бэкусом его речи в программировании произошли заметные сдвиги, появились функциональные и объектно-ориентированные технологии, и с их помощью удалось преодолеть то, что Бэкус называл «интеллектуальным фон-неймановским бутылочным горлом». Однако архитектурная первопричина данного явления, врожденная болезнь канала между памятью и процессором – его ограниченная пропускная способность – не исчезла, несмотря на прогресс в области технологии за прошедшие с тех пор 30 лет. С годами эта проблема постоянно усугубляется, поскольку скорость работы памяти растет гораздо медленнее, чем производительность процессоров, и разрыв между ними становится все больше .
Фон-неймановская архитектура компьютера не является единственно возможной. С точки зрения организации обмена командами между процессором и памятью все компьютеры можно разделить на четыре класса (классификация Флинна) [11]:
SISD (Single Instruction Single Data) – «один поток команд, один поток данных»»;
SIMD (Single Instruction Multiply Data) – один поток команд, много потоков данных;
MISD (Multiple Instruction Single Data) – много потоков команд, один поток данных;
MIMD (Multiple Instruction Multiple Data) – много потоков команд, много потоков данных.