Трудности многопоточного программирования
На первый взгляд, может показаться, что писать программы, использующие возможности современных многоядерных процессоров на 100%, проще простого. Однако, это, мягко говоря, не так.
Во-первых, само по себе многопоточное программирование довольно сложная и коварная штука, и у многих программистов есть проблемы с возможностью представить себе в голове, как программа будет работать на самом деле. Вследствие этого, многопоточные приложения обычно подвержены появлению в них очень тонких и неочевидных ошибок, которые трудно воспроизвести и обнаружить.
Во-вторых, переход от линейного решения задачи к многопоточному ее варианту, который был бы при этом еще и эффективнее линейного, чаще всего есть весьма и весьма нетривиальная задача. Программа такого многопоточного решения почти всегда объемнее и сложнее линейной программы, а значит, ее дольше писать, сложнее отлаживать и дороже сопровождать. Более того, в мире существует много задач, которые крайне неохотно поддаются распараллеливанию.
Виртуальная многоядерность
Суть и предпосылки
Основная проблема современных ядер – это невозможность эффективно использовать имеющиеся большие ресурсы специализированных функциональных исполнительных устройств подсистемы обработки. Причина этого не плохо разработанные структуры ядра, а свойства реальных программ. При наличии информационных зависимостей между командами даже с учетом самых современных технологий внеочередного выполнения команд, переименования регистров неизбежны простои специализированных функциональных исполнительых устройств подсистемы обработки. Еще большие простои исполнительых устройств возникают при обращениях к кэш-памяти последнего уровня или к оперативной памяти (десятки и даже сотни тактов)
Например, при выполнении реальных программ, типичных для набора команд архитектуры IA-32/64, используется не более 50% (причем это верхняя оценка, а зачастую и около 35%) исполнительных ресурсов ядра, что означает неэффективное использование возможностей ядра. При выполнении в ядре одного потока увеличить эффективность использования ресурсов ядра очень трудно.
Было бы логично организовать работу ядра таким образом, чтобы в нем одновременно выполнялись несколько потоков. При правильной организации такой работы можно ожидать увеличения эффективности использования ресурсов одного физического ядра, а значит и увеличения производительности этого ядра (ускорения выполнения нескольких потоков при их одновременном выполнении по сравнению с последовательным выполнением при единоличном использовании всех ресурсов физического ядра). Именно эту идею и реализует технология виртуальной многоядерности. Переключения между одновременно выполняемыми потоками в одном ядре не должны существенно сказываться на производительности каждого потока.
Варианты организации многопоточной виртуальности
Многопоточное физическое ядро параллельно (или квазипараллельно) выполняет команды из разных потоков.
Существует два основных типа многопоточных ядер:
выполняющие в одном такте команды только из одного потока;
выполняющие в одном такте команды из нескольких потоков.
На рис. 33.3 представлены 4 варианта организации выполнения потоков в ядре.
Первый вариант отображает традиционную работу ядра при выполнении потоков.
В каждый момент времени все ресурсы ядра принадлежат одному потоку. При возникновении прерывания, либо исключения или при вызове операционной системы (ОС) текущий поток снимается с выполнения (переводится в режим ожидания своей очереди) и начинают выполняться потоки ОС. После выполнения потоков ОС происходит либо запуск потока другого приложения, либо возобновление прерванного потока.
Второй вариант (блокирующая многопоточность) иллюстрирует организацию многопоточности, когда аппаратно реализованное переключение потоков происходит при возникновении достаточно длительной задержки при выполнении потока (например, данные отсутствуют в кэш-памяти, происходит обращение в оперативную память, по истечению кванта времени).
Рис. 33.3. Варианты организации выполнения потоков в ядре
Третий вариант (многопоточность с чередованием) показывает, что переключение на очередной поток происходит каждый такт. В каждом такте все ресурсы ядра принадлежат только одному потоку.
Четвертый вариант иллюстрирует идею, когда в одном такте работы ядра выполняются команды нескольких потоков. Такая реализация виртуальной многопоточности называется одновременной многопоточностью (SMT – в англоязычной терминологии).
Многие современные суперскалярные ядра, выполняющие команды с изменением их очередности, поддерживают принцип одновременной многопоточности, например, в ядрах процессоров фирмы IBM Power 6, Power 7, Power 8, фирмы Intel - в процессорах со структурами Nehalem, Sandy Bridge, Haswell.
Блокирующая многопоточность (вариант 2) реализована в процессорах фирмы Intel линии Itanium.
Многопоточность с чередованием была реализована в ядрах процессоров UltraSPARC различных серий фирмы Sun.
Дата добавления: 2016-06-05; просмотров: 2711;