Последние темы
» Вити больше нет!автор bug19 Пн Фев 20 2023, 19:54
» Собираем оригинальный Орион 128
автор bug19 Пн Фев 20 2023, 19:47
» Проблема плющеного экрана ОРИОНА
автор kanzler Пн Ноя 28 2022, 12:05
» Орион 128 и его клоны возрождение 2019-2022 год
автор kanzler Пн Ноя 28 2022, 12:03
» Электроника КР-04. Информация, документы, фото.
автор kanzler Пн Ноя 28 2022, 12:02
» Новости форума
автор kanzler Пн Ноя 28 2022, 11:52
» Орион-128 НГМД запуск 2021 года
автор matrixplus Сб Сен 10 2022, 17:36
» ПЗУ F800 для РК86
автор ведущий_специалист Сб Сен 10 2022, 10:37
» Микропроцессорная лаборатория "Микролаб К580ИК80", УМК-80, УМПК-80 и др.
автор Электротехник Вт Июл 26 2022, 19:33
» Орион-128 SD карта в Орионе
автор matrixplus Чт Июн 02 2022, 09:00
» 7 Мая. День Радио!
автор Viktor2312 Чт Май 12 2022, 10:58
» Серия: Массовая радио библиотека. МРБ
автор Viktor2312 Ср Май 11 2022, 12:17
» Полезные книги
автор Viktor2312 Пн Май 09 2022, 15:07
» Орион 128 Стандарты портов и системной шины Х2
автор matrixplus Вс Май 08 2022, 23:08
» Орион-128 и Орион ПРО еще раз про блоки питания
автор matrixplus Вс Май 08 2022, 19:09
» Орион-128 Программаторы
автор matrixplus Вс Май 08 2022, 19:02
» Орион ПРО история сборки 2021 до 2022
автор matrixplus Вс Май 08 2022, 18:47
» Анонсы монет (New coin).
автор Viktor2312 Сб Май 07 2022, 23:11
» Хочу свой усилок для квартиры собрать не спеша
автор Viktor2312 Сб Май 07 2022, 19:33
» Амфитон 25у-002С
автор Viktor2312 Сб Май 07 2022, 09:38
» Майнер: T-Rex
автор Viktor2312 Вс Май 01 2022, 09:12
» GoWin. Изучение документации. SUG100-2.6E_Gowin Software User Guide. Среда разработки EDA.
автор Viktor2312 Пн Апр 25 2022, 01:01
» GoWin. Изучение документации. UG286-1.9.1E Gowin Clock User Guide.
автор Viktor2312 Сб Апр 23 2022, 18:22
» GoWin. Documentation Database. Device. GW2A.
автор Viktor2312 Ср Апр 20 2022, 14:08
» GOWIN AEC IP
автор Viktor2312 Ср Апр 20 2022, 12:08
Самые активные пользователи за месяц
Нет пользователей |
Поиск
Tesla. CUDA. Статьи.
Страница 1 из 1 • Поделиться
Tesla. CUDA. Статьи.
1
.
Содержание 1 части:
Введение
Фундаментальные основы
Современная архитектура
Нити
____Когда пишут об архитектуре NVIDIA CUDA, принято начать с экскурса в историю развития GPU, роста их функциональных возможностей, как они, шаг за шагом, превращались в универсальные вычислительные устройства. Но, в данной статье этому не будет уделено никакого внимания, видеоускорители уже эволюционировали в процессоры. И разработчикам, и пользователям программного обеспечения в принципе всё равно, был ли этот путь ровным или извилистым. Как правило, новые процессорные архитектуры — есть эволюционное развитие предшествующих. Например, не будет очень большим преувеличением сказать, что процессор Core есть сильно улучшенный, доведенный до архитектурного совершенства, многоядерный Pentium II–III. А процессоры Phenom отличаются от первых Атлонов поддержкой SSE, "прикрученным" контроллером памяти, большими кэшами, 64-битным расширением набора инструкций и мелкими архитектурными улучшениями, такими как предвыборка данных и новые алгоритмы предсказания условных переходов. Но это нельзя сказать о технологии CUDA. Это принципиально новая архитектура, которая стала возможной только благодаря невероятному улучшению технологических процессов за последние годы. Миллиарды транзисторов на кристалле обернулись сотнями вычислительных CUDA-модулей. Причём, важно, что этот рост техпроцесса произошёл «вширь», а не «вглубь». То есть, вылился не в повышение тактовой частоты, а именно в увеличение площадей кристалла. Если бы открыли какой-то способ повышения тактовой частоты, вместо утончения норм производства, то ни о какой CUDA и речи бы ни шло. Так как современные, высоко конвейеризированные CPU достигли бы высоких частот и превосходной производительности в однопоточном режиме, а места для большого количества низкочастотных по своей природе CUDA-процессоров, на кристалле не нашлось бы.
____Но случилось так, как случилось и технологии многоядерной мультипоточности, среди которых CUDA — самая радикальная, выходят на первый план.
____Итак, суть архитектуры — это размещение на кристалле нескольких десятков процессорных ядер с собственной памятью, каждое из которых одновременно выполняет несколько сотен программных потоков. И, в данном случае термин «нить», как нельзя лучше подходит для описания одной из тысяч параллельно выполняющихся частей CUDA-программы. Как будет описано далее, эти нити переплетаются между собой и они ещё сплетены в более крупные структуры, как отдельные тонкие провода в большом кабеле. Процессорные ядра, называемые в CUDA-терминологии мультипроцессорами, имеют собственный доступ к глобальной памяти, расположенной на видеоплате и устройство обменивается данными с CPU через шину PCI-Express.
____Всегда модно сравнивать скорость современных настольных компьютеров с суперкомпьютерными системами прошлого, восхищаясь ростом производительности. Но архитектура настольных процессоров, до самого последнего времени была максимум двухпоточной, и пусть четырехъядерные процессоры появились в изобилии на рынке, двуядерные модели также продолжают вовсю выпускаться. В этом плане, CUDA-устройство гораздо больше похоже по архитектуре на настоящий кластерный суперкомпьютер из сотен вычислительных узлов. Только размещенный на одном кристалле. И разные элементы архитектуры взяты из суперкомпьютеров самых разных лет.
____Необходимо сразу отметить, что программироваться это CUDA-устройство должно по принципам настоящего суперкомпьютера. С мерками программирования для PC, к нему подходить нельзя.
____Есть два факта, их можно назвать законами вычислительной техники, которые составляют теоретическую основу востребованности высокопараллельных вычислительных архитектур. Потребляемая мощность процессора пропорциональна примерно квадрату тактовой частоты, примерно степени 2,5. То есть, процессор с тактовой частотой 3 ГГц потребляет больше, чем 9 процессоров частотой 1 ГГц. Таким образом, для параллельной программы энергоэффективность массы мелких процессоров будет выше в три раза. Иными словами, многоядерный процессор, с той же потребляемой энергией, будет в три раза производительнее при исполнении параллельного кода.
____Второй факт относится уже к программному обеспечению и алгоритмам. Если задача распараллеливается, то есть, допускает реализацию с помощью параллельного алгоритма, который может исполняться одновременно на нескольких процессорах, то чем на большее количество потоков она уже распараллелена, то тем больше вероятность, что задача может быть распараллелена на ещё большее количество потоков. Например, большое количество задач не допускает параллельной реализации, многие распараллеливаются только на два потока, а если алгоритм допускает три потока, то весьма вероятно, что он распараллелиться и на четыре и на пять и на шесть потоков.
____А если программа имеет десять потоков, то, скорее всего, можно будет использовать и двадцать, и пятьдесят нитей. И дальше — больше: где сто, там и тысяча. И так далее. Таким образом, если отправляться в мир параллельных вычислений, то имеет смысл бросаться, как в омут головой. Потому, что после превышения количества потоков определенной величины уже становится безразлично, сколько их, их просто много.
____Такая ситуация типична для вычислительных задач с большими объёмами данных, которые по своей природе, в принципе, допускают параллельный алгоритм решения. А если такого нет, то можно и не надеяться на увеличение производительности в обозримом будущем, так как тактовая частота современных CPU растёт очень медленно. В таких случаях, выгодно реализовать многопоточный алгоритм, пусть он будет и на порядок более вычислительно затратным, всё равно, площади кристаллов девать некуда и, на мультипроцессорной системе такой, сам по себе малоэффективный алгоритм, будет работать быстрее. Но, уже имея задачу с тысячами потоков, можно заранее адаптировать вычислительную архитектуру с учётом мультипоточности, сконцентрироваться на общей производительности программы, а не каждой отдельной нити, сильно сэкономив на многих традиционных архитектурных деталях.
____Важно также, что конструировать низкочастотный процессор гораздо легче. Проще реализовать разнообразную сложную логику, большинство инструкций исполняются за один такт, что упрощает планировщик выполнения инструкций и требует меньшего количества разнообразных буферов и очередей инструкций. А также упрощает и делает более удобной саму ISA. (ISA — Instruction Set Architecture, архитектура системы команд). И пропускная способность памяти растёт гораздо быстрее, чем уменьшается её латентность. Таким образом, обеспечить данными множество низкочастотных CPU гораздо проще и дешевле, чем один высокочастотный. Так как он будет часто простаивать, в ожидании данных из медленной памяти.
____Эти факты, взятые вместе, делают многопоточную технологию CUDA востребованной и перспективной.
____Среди всевозможных компьютерных задач можно выделить три больших класса: серверные задачи работы с базами данных, задачи управления (например, внутренняя логика какой–нибудь компьютерной игры или симулятора) и вычислительные задачи. Архитектура CUDA, в её текущей аппаратной реализации ориентирована, в первую очередь, на вычислительные задачи. Так называемые compute bound applications. Это не обязательно решение математических уравнений, это может быть и обработка изображений, и проверка ключей, и анализ строк. Но суть в том, что надо считать, считать и считать, а не различные функции вызывать с ветвлениями.
____Итак, возьмём для конкретности последнюю реализацию CUDA в графическом процессоре GT200. Он имеет 30 мультипроцессоров, один мультипроцессор работает на частоте примерно 1,4 GHz, имеет 8 исполнительных устройств общего назначения, выполняющих за такт типичные операции, как то: сложение и умножение вещественных чисел типа float, сравнения, условные переходы, логические операции, операции с регистрами.
____Один мультипроцессор может одновременно выполнять 1024 программных нитей. Но исполнительных устройств всего 8, не считая специального устройства вычисления библиотечных функций типа синуса и косинуса. Поэтому инструкции всех 1024 потоков в один момент исполняться не могут. Нити разбиты на группы по 32 штуки, называемые warp. Этот термин можно художественно перевести как пучок нитей, само английское значение слова имеет, видимо, морское происхождение, связанное с тросами. Очень, кстати, показательно. В один момент исполняется один варп, он исполняется 4 такта (8 исполнительных устройств за 4 такта исполняют 32 операции). Если там нет длинной специальной инструкции. Но, из всех 32 нитей, в один заход реально исполняются только те, которые находятся в одном месте программы. То есть, исполняют одну и ту же инструкцию программы. Техническими словами, если совпадают указатели инструкций, другими словами — адреса инструкций в коде программы.
____Каждая нить CUDA-приложения исполняет одну и ту же программу, но алгоритму доступен номер нити среди всех запущенных, и поэтому алгоритм может произвольно меняться, в зависимости от её номера. Можно запустить хоть 10 000 различных подпрограмм, для каждой нити выбрав свою, в самом начале кода. Но это будет неэффективно, из-за вышеприведенной особенности исполнения варпа целиком. Когда все нити, внутри каждого варпа, имеют одинаковый путь исполнения, достигается максимальная производительность.
____Если ветвления, в программе нити, уводят её в сторону от других, она начинает исполнять отдельный кусок программы, тогда время исполнения мультипроцессором целого варпа удваивается. Потому, что сначала он исполняет инструкцию, соответствующую 31 нити, а потом инструкцию оставшейся нити. Если половина варпа, 16 нитей, будет в одном месте программы, а другая половина — в другом, то варп тоже будет исполняться в два раза медленней. А если все нити варпа разбредутся по разным частям программы и будут выполнять каждая свои инструкции, то скорость упадет в 32 раза.
____Но, именно для вычислительных задач, такой сильный разброс не характерен и с ним можно успешно бороться, что определяет наилучшую область применения технологии. В плотных вычислительных циклах нити имеют, как правило, сходный путь. Впрочем, даже при полностью сериализованном (от английского слова serial), иными словами, последовательном исполнении, CUDA-устройство имеет неплохую производительность, благодаря большому количеству мультипроцессоров и достаточно высокой тактовой частоте. И генератор машинного кода для CUDA анализирует программу, детектирует циклы и вставляет точки реконвергенции для нитей, где они ждут друг друга, если расходились, чтобы дальше пойти дружным шагом, а не совсем разбредаться из-за первого же дивергентного ветвления.
____И, надо сказать, что уже различные варпы, то есть пучки или связки нитей по 32 штуки, могут выполняться полностью независимо. Каждый варп может выполнять инструкции из любого места программы. Имея 1024 нити, в стадии выполнения на мультипроцессоре, можно, таким образом, иметь 32 активных варпа, исполняющихся параллельно. Для исполнения выбирается тот варп, для инструкций которого подгружены данные из глобальной памяти, т. е. который готов для исполнения.
____Схематическое изображение исполняющейся CUDA-программы «в разрезе». Большие синие прямоугольники обозначают 30 мультипроцессоров. На каждом 4 активных блока нитей, обозначенных кружками. Каждый блок состоит из 4 варпов по 32 нити. Варп обозначен прямоугольником. Варп состоит из двух полуварпов по 16 нитей. Каждая нить обозначена точкой. Итого имеем 15360 (30*4*4*32) одновременно исполняющихся нитей.
Конец 1 части.
Параллельные вычислительные процессоры NVIDIA: настоящее и будущее.
Содержание 1 части:
Введение
Фундаментальные основы
Современная архитектура
Нити
Введение.
____Когда пишут об архитектуре NVIDIA CUDA, принято начать с экскурса в историю развития GPU, роста их функциональных возможностей, как они, шаг за шагом, превращались в универсальные вычислительные устройства. Но, в данной статье этому не будет уделено никакого внимания, видеоускорители уже эволюционировали в процессоры. И разработчикам, и пользователям программного обеспечения в принципе всё равно, был ли этот путь ровным или извилистым. Как правило, новые процессорные архитектуры — есть эволюционное развитие предшествующих. Например, не будет очень большим преувеличением сказать, что процессор Core есть сильно улучшенный, доведенный до архитектурного совершенства, многоядерный Pentium II–III. А процессоры Phenom отличаются от первых Атлонов поддержкой SSE, "прикрученным" контроллером памяти, большими кэшами, 64-битным расширением набора инструкций и мелкими архитектурными улучшениями, такими как предвыборка данных и новые алгоритмы предсказания условных переходов. Но это нельзя сказать о технологии CUDA. Это принципиально новая архитектура, которая стала возможной только благодаря невероятному улучшению технологических процессов за последние годы. Миллиарды транзисторов на кристалле обернулись сотнями вычислительных CUDA-модулей. Причём, важно, что этот рост техпроцесса произошёл «вширь», а не «вглубь». То есть, вылился не в повышение тактовой частоты, а именно в увеличение площадей кристалла. Если бы открыли какой-то способ повышения тактовой частоты, вместо утончения норм производства, то ни о какой CUDA и речи бы ни шло. Так как современные, высоко конвейеризированные CPU достигли бы высоких частот и превосходной производительности в однопоточном режиме, а места для большого количества низкочастотных по своей природе CUDA-процессоров, на кристалле не нашлось бы.
____Но случилось так, как случилось и технологии многоядерной мультипоточности, среди которых CUDA — самая радикальная, выходят на первый план.
____Итак, суть архитектуры — это размещение на кристалле нескольких десятков процессорных ядер с собственной памятью, каждое из которых одновременно выполняет несколько сотен программных потоков. И, в данном случае термин «нить», как нельзя лучше подходит для описания одной из тысяч параллельно выполняющихся частей CUDA-программы. Как будет описано далее, эти нити переплетаются между собой и они ещё сплетены в более крупные структуры, как отдельные тонкие провода в большом кабеле. Процессорные ядра, называемые в CUDA-терминологии мультипроцессорами, имеют собственный доступ к глобальной памяти, расположенной на видеоплате и устройство обменивается данными с CPU через шину PCI-Express.
____Всегда модно сравнивать скорость современных настольных компьютеров с суперкомпьютерными системами прошлого, восхищаясь ростом производительности. Но архитектура настольных процессоров, до самого последнего времени была максимум двухпоточной, и пусть четырехъядерные процессоры появились в изобилии на рынке, двуядерные модели также продолжают вовсю выпускаться. В этом плане, CUDA-устройство гораздо больше похоже по архитектуре на настоящий кластерный суперкомпьютер из сотен вычислительных узлов. Только размещенный на одном кристалле. И разные элементы архитектуры взяты из суперкомпьютеров самых разных лет.
____Необходимо сразу отметить, что программироваться это CUDA-устройство должно по принципам настоящего суперкомпьютера. С мерками программирования для PC, к нему подходить нельзя.
Фундаментальные основы.
____Есть два факта, их можно назвать законами вычислительной техники, которые составляют теоретическую основу востребованности высокопараллельных вычислительных архитектур. Потребляемая мощность процессора пропорциональна примерно квадрату тактовой частоты, примерно степени 2,5. То есть, процессор с тактовой частотой 3 ГГц потребляет больше, чем 9 процессоров частотой 1 ГГц. Таким образом, для параллельной программы энергоэффективность массы мелких процессоров будет выше в три раза. Иными словами, многоядерный процессор, с той же потребляемой энергией, будет в три раза производительнее при исполнении параллельного кода.
____Второй факт относится уже к программному обеспечению и алгоритмам. Если задача распараллеливается, то есть, допускает реализацию с помощью параллельного алгоритма, который может исполняться одновременно на нескольких процессорах, то чем на большее количество потоков она уже распараллелена, то тем больше вероятность, что задача может быть распараллелена на ещё большее количество потоков. Например, большое количество задач не допускает параллельной реализации, многие распараллеливаются только на два потока, а если алгоритм допускает три потока, то весьма вероятно, что он распараллелиться и на четыре и на пять и на шесть потоков.
____А если программа имеет десять потоков, то, скорее всего, можно будет использовать и двадцать, и пятьдесят нитей. И дальше — больше: где сто, там и тысяча. И так далее. Таким образом, если отправляться в мир параллельных вычислений, то имеет смысл бросаться, как в омут головой. Потому, что после превышения количества потоков определенной величины уже становится безразлично, сколько их, их просто много.
____Такая ситуация типична для вычислительных задач с большими объёмами данных, которые по своей природе, в принципе, допускают параллельный алгоритм решения. А если такого нет, то можно и не надеяться на увеличение производительности в обозримом будущем, так как тактовая частота современных CPU растёт очень медленно. В таких случаях, выгодно реализовать многопоточный алгоритм, пусть он будет и на порядок более вычислительно затратным, всё равно, площади кристаллов девать некуда и, на мультипроцессорной системе такой, сам по себе малоэффективный алгоритм, будет работать быстрее. Но, уже имея задачу с тысячами потоков, можно заранее адаптировать вычислительную архитектуру с учётом мультипоточности, сконцентрироваться на общей производительности программы, а не каждой отдельной нити, сильно сэкономив на многих традиционных архитектурных деталях.
____Важно также, что конструировать низкочастотный процессор гораздо легче. Проще реализовать разнообразную сложную логику, большинство инструкций исполняются за один такт, что упрощает планировщик выполнения инструкций и требует меньшего количества разнообразных буферов и очередей инструкций. А также упрощает и делает более удобной саму ISA. (ISA — Instruction Set Architecture, архитектура системы команд). И пропускная способность памяти растёт гораздо быстрее, чем уменьшается её латентность. Таким образом, обеспечить данными множество низкочастотных CPU гораздо проще и дешевле, чем один высокочастотный. Так как он будет часто простаивать, в ожидании данных из медленной памяти.
____Эти факты, взятые вместе, делают многопоточную технологию CUDA востребованной и перспективной.
Современная архитектура.
____Среди всевозможных компьютерных задач можно выделить три больших класса: серверные задачи работы с базами данных, задачи управления (например, внутренняя логика какой–нибудь компьютерной игры или симулятора) и вычислительные задачи. Архитектура CUDA, в её текущей аппаратной реализации ориентирована, в первую очередь, на вычислительные задачи. Так называемые compute bound applications. Это не обязательно решение математических уравнений, это может быть и обработка изображений, и проверка ключей, и анализ строк. Но суть в том, что надо считать, считать и считать, а не различные функции вызывать с ветвлениями.
____Итак, возьмём для конкретности последнюю реализацию CUDA в графическом процессоре GT200. Он имеет 30 мультипроцессоров, один мультипроцессор работает на частоте примерно 1,4 GHz, имеет 8 исполнительных устройств общего назначения, выполняющих за такт типичные операции, как то: сложение и умножение вещественных чисел типа float, сравнения, условные переходы, логические операции, операции с регистрами.
Нити.
____Один мультипроцессор может одновременно выполнять 1024 программных нитей. Но исполнительных устройств всего 8, не считая специального устройства вычисления библиотечных функций типа синуса и косинуса. Поэтому инструкции всех 1024 потоков в один момент исполняться не могут. Нити разбиты на группы по 32 штуки, называемые warp. Этот термин можно художественно перевести как пучок нитей, само английское значение слова имеет, видимо, морское происхождение, связанное с тросами. Очень, кстати, показательно. В один момент исполняется один варп, он исполняется 4 такта (8 исполнительных устройств за 4 такта исполняют 32 операции). Если там нет длинной специальной инструкции. Но, из всех 32 нитей, в один заход реально исполняются только те, которые находятся в одном месте программы. То есть, исполняют одну и ту же инструкцию программы. Техническими словами, если совпадают указатели инструкций, другими словами — адреса инструкций в коде программы.
____Каждая нить CUDA-приложения исполняет одну и ту же программу, но алгоритму доступен номер нити среди всех запущенных, и поэтому алгоритм может произвольно меняться, в зависимости от её номера. Можно запустить хоть 10 000 различных подпрограмм, для каждой нити выбрав свою, в самом начале кода. Но это будет неэффективно, из-за вышеприведенной особенности исполнения варпа целиком. Когда все нити, внутри каждого варпа, имеют одинаковый путь исполнения, достигается максимальная производительность.
____Если ветвления, в программе нити, уводят её в сторону от других, она начинает исполнять отдельный кусок программы, тогда время исполнения мультипроцессором целого варпа удваивается. Потому, что сначала он исполняет инструкцию, соответствующую 31 нити, а потом инструкцию оставшейся нити. Если половина варпа, 16 нитей, будет в одном месте программы, а другая половина — в другом, то варп тоже будет исполняться в два раза медленней. А если все нити варпа разбредутся по разным частям программы и будут выполнять каждая свои инструкции, то скорость упадет в 32 раза.
____Но, именно для вычислительных задач, такой сильный разброс не характерен и с ним можно успешно бороться, что определяет наилучшую область применения технологии. В плотных вычислительных циклах нити имеют, как правило, сходный путь. Впрочем, даже при полностью сериализованном (от английского слова serial), иными словами, последовательном исполнении, CUDA-устройство имеет неплохую производительность, благодаря большому количеству мультипроцессоров и достаточно высокой тактовой частоте. И генератор машинного кода для CUDA анализирует программу, детектирует циклы и вставляет точки реконвергенции для нитей, где они ждут друг друга, если расходились, чтобы дальше пойти дружным шагом, а не совсем разбредаться из-за первого же дивергентного ветвления.
____И, надо сказать, что уже различные варпы, то есть пучки или связки нитей по 32 штуки, могут выполняться полностью независимо. Каждый варп может выполнять инструкции из любого места программы. Имея 1024 нити, в стадии выполнения на мультипроцессоре, можно, таким образом, иметь 32 активных варпа, исполняющихся параллельно. Для исполнения выбирается тот варп, для инструкций которого подгружены данные из глобальной памяти, т. е. который готов для исполнения.
____Схематическое изображение исполняющейся CUDA-программы «в разрезе». Большие синие прямоугольники обозначают 30 мультипроцессоров. На каждом 4 активных блока нитей, обозначенных кружками. Каждый блок состоит из 4 варпов по 32 нити. Варп обозначен прямоугольником. Варп состоит из двух полуварпов по 16 нитей. Каждая нить обозначена точкой. Итого имеем 15360 (30*4*4*32) одновременно исполняющихся нитей.
Конец 1 части.
Viktor2312- RIP
- Сообщения : 15492
Дата регистрации : 2012-08-10
Возраст : 45
Откуда : Пятигорск
.
2
.
Содержание 2 части:
Память
Локальная память
Регистры и инструкции
Программная модель
Компилирование
Сравнительная производительность
____Память, в текущих CUDA-устройствах, находится на отдельных микросхемах на видеоплате, как системная память на системной. Поэтому, время доступа к ней исчисляется несколькими сотнями тактов. Но, имея сотни исполняющихся нитей, можно частично скрыть эту латентность, все равно в один момент может исполняться только группа из 32 нитей. Остальные пока подождут данных. Таким образом, можно сэкономить на размерах различных кэшей и, вместо памяти, на кристалле разместить ещё больше исполнительных устройств. Вот в этом проявляется использование существенной многопоточности алгоритма.
____Также, есть одна специальная возможность, доставшаяся от далеких предков: это доступная только для чтения текстурная память, которая читается при помощи текстурных блоков. Она имеет небольшой кэш 6–8 Кб на мультипроцессор и общий L2-кэш 256 Кб на всё устройство. С её помощью, можно ускорить доступ к немодифицируемым, в процессе работы программы, данным. Можно сказать, исходным данным. Текстурные кэши оптимизированы для двумерных массивов, что предоставляет неплохую оптимизационную возможность для приложений, которые работают с данными такого типа, изображениями например.
____Но всё же, латентность глобальной памяти очень велика, её легче скрыть, если она читается по такой схеме: последовательно читаются данные, они обрабатываются и в глобальную память пишется результат.
____Но часто бывает, что нужно хранить большой объем промежуточных вычислений. Для этого существует локальная память мультипроцессора, которая в CUDA-терминологии называется разделяемой (shared). Потому, что она общая для всех нитей одного блока. Да, нити объединяются в блоки, это задается программистом при запуске программы. В отличие от размера варпа, равного 32 нитям и задаваемого требованиями железа, размер блока может варьироваться. Для простоты изложения концепции можно было бы считать, что в один момент мультипроцессор может исполнять один блок, состоящий из 1024 нитей, который обладает всей локальной памятью мультипроцессора, которая вся целиком доступна каждой нити блока. Но в реальности, размер блока может быть любым, в пределах 512 нитей и кратным размеру варпа, и мультипроцессор может одновременно выполнять несколько блоков, и память мультипроцессора, в этом случае, делится поровну между этими блоками.
____Размер этой памяти составляет всего 16 Кб. Но это соизмеримо с размером кэша данных первого уровня современных процессоров, средняя скорость доступа к ней довольно высока и составляет несколько тактов.
____Таким образом, CUDA-программа может работать с памятью по одной из двух схем: либо читать и писать всё в глобальную память, надеясь на то, что количество потоков, в значительной мере скроет латентность, либо разбить данные задачи на куски и последовательно помещать их в локальную память для обработки.
____Первый вариант оправдан, если программа перенасыщена вычислениями и читает, а также пишет в память относительно редко. Второй вариант предпочтительнее, он позволяет достичь близкой, к теоретическому максимуму, производительности, но не всегда возможен. Но первый легко программировать, не требуется специальной оптимизации. Возможна и комбинация двух подходов.
____Также есть общая для всех нитей, доступная только для чтения, память программных констант, размером 64 Кб, с быстрым доступом. У каждого мультипроцессора есть 8 Кб специального кэша для констант.
____Помимо разделяемой памяти блока и общей глобальной памяти, каждой нити доступны собственно её регистры. Типичное их количество — 32 обычных 32-битных регистров. Точное количество регистров задаётся программистом, от этого зависит максимальное количество нитей, выполняющихся на мультипроцессоре, поскольку каждый мультипроцессор имеет банк из 16384 регистров, которые делятся между нитями.
____И опять, благодаря большому количеству нитей на мультипроцессоре, можно полностью скрыть латентность доступа к файлу регистров и иметь много регистров. Сама же ISA вполне обычна, это очень стандартный, простой и компактный, так называемый скалярный RISC с некоторыми важными ограничениями: GT200 не поддерживает С++, то есть, нет виртуальных функций и нет рекурсивных функций. Потому, что нет стека, всё на регистрах. Для вычислительных задач это непринципиальный момент, всё равно, в главных вычислительных циклах нельзя пользоваться виртуальными функциями, а рекурсивный алгоритм можно изменить так, чтобы не было вызова функций.
____Широко используются предикатные регистры, то есть значение регистра устанавливается в зависимости от значения логического выражения, вроде (a>b), которое либо истина, либо ложь. И далее, в коде следующей инструкции, например, перехода, задаётся, при каком значении какого предикатного регистра она выполняется. Так, переход становится условным. Очень удобно, на самом деле, и для компиляторов, и для ручного кодирования.
____Что нужно сделать, чтобы запустить CUDA-программу? Надо загрузить исходные данные в память CUDA-устройства и запустить саму исполняемую функцию, указав ей количество нитей в блоке и общее количество блоков. Каждая из тысяч нитей прочитает в системной переменной свой номер, в соответствии с ним — свои данные для работы и запишет в соответствующую область памяти результат.
____Самый простой пример: нужно вычислить некую математическую функцию f от массива значений из 128 000 элементов. Мы загружаем этот массив элементов в память устройства, запускаем программу, её код инструкций система загружает на все мультипроцессоры. При запуске мы указываем, например, размер блока 128 нитей, а количество блоков 1000. Каждый мультипроцессор обрабатывает 8 блоков из 128 нитей, каждая нить читает, в соответствии со своим номером, элемент массива чисел, вычисляет функцию и записывает обратно. По мере выполнения всех нитей блока, мультипроцессор загружает на выполнение новые блоки. И далее, мы читаем данные из устройства обратно.
____Это самый простой пример, но сразу можно сказать, что производительность его, в первую очередь, зависит от того, сколько серьезных ветвлений есть в алгоритме функции f, насколько путь исполнения зависит от значений аргумента. Если сильно дивергентных, то есть по-разному исполняющихся в зависимости от аргумента, ветвлений мало, то производительность будет очень большой.
____Но нити не обязаны исполняться совсем независимо друг от друга. Для нитей внутри одного блока (это примерно 256 нитей), есть стандартные инструкции синхронизации исполнения Wait — ждать, когда все нити синхронизируются. Напомню, что нити абсолютно произвольны в своем поведении и совсем не похожи на SSE-инструкции. Есть так же инструкции атомарной записи данных в память блока, для обмена данными между нитями.
____То есть, нити в одном блоке могут переплетаться между собой. А вот блоки, в рамках CUDA-идеологии, предполагаются более независимыми. Они как будто бы исполняются на разных, далеко друг от друга расположенных, кластерах одного большого суперкомпьютера. Каждый из этих кластеров получил свое задание и, в каком порядке они исполняются, программисту неизвестно. Но некоторую синхронизацию, в частных случаях, можно организовать с помощью флагов в глобальной памяти. Например, организовать счетчик выполнения и старта блоков и, в зависимости от номера, блок будет выполнять свою часть задачи. Например, последний исполняющийся блок узнает, что он последний и может выполнить специальный завершающий этап работы. Или можно запустить новую программу, новый этап вычислений, который воспользуется сохраненными в памяти GPU результатами работы предыдущей программы.
____На практике, принципиальная схема создания CUDA-программы такова: поставляемый NVIDIA компилятор встраивается в среду разработки, он компилирует исходный файл с кодом функции, которая должна исполняться на устройстве и превращает его в ассемблерный код для CUDA-устройства, который присоединяется к программе, как ресурс данных. При запуске программы на конкретной системе, этот код, с помощью библиотечной функции, передаётся видеодрайверу, который компилирует его для имеющегося CUDA-устройства в машинный код, специфичный для данного устройства. Так обеспечивается совместимость между редакциями архитектур. И далее, с помощью вызова библиотечных функций из кода основной программы, данные загружаются в GPU и для исполнения на устройстве вызывается скомпилированная драйвером функция.
____Можно также, на этапе компилирования, дополнительно создать несколько вариантов машинного кода для различных типов CUDA-GPU. Тогда драйвер, при запуске программы, может не компилировать ассемблерный код в машинный, а взять уже готовый вариант, если он существует для данного GPU. А если его нет (например, этот GPU ещё не вышел в момент написания программы), то будет компилироваться универсальный ассемблерный код.
____Итак, мы ознакомились с главными моментами архитектуры CUDA, но смысл её существования в дополнительной производительности. Что можно, на данный момент, ожидать от присутствующих на рынке CUDA-устройств? Для сравнения с тридцатью мультипроцессорами архитектуры GT200, возьмём четырехъядерные Lynnfield вдвое большей частоты и сделаем, для начала, самую грубую оценку теоретического максимума в вычислениях, с вещественными числами одинарной точности. Как раз, у наиболее массовых моделей Lynnfield, частота примерно вдове выше массовых моделей GT200.
____GT200, за такт, теоретически выполняет 8*30=240 инструкций, а одно ядро Lynnfield, за два такта (что соответствует одному такту GT200), начинает выполнение четырех SSE-инструкций с 4 парами float-переменных. Таким образом, получается 4 ядра*2 такта*2 инструкции*4 переменных=64 инструкции.
____В теории, GT200 может быть примерно в 5 раз быстрее. Кстати, GT200 может за тот же свой такт выполнять инструкцию mul–add, умножения двух операндов и сложения с третьим. Если её посчитать, то в теории и в 10. Но на самом деле, для большинства задач, разница в этом моменте в 2 раза, что является мелочью, ничего бы не изменилось в этом мире, если бы GT200 не умел выполнять mul–add.
____Но на практике, все может обернуться самым разным образом. И тот, и другой теоретический максимум, не так легко, на самом деле, достичь. В архитектуре нынешних GPU есть несколько темных углов, которые могут убить реальную производительность, даже теоретически полностью параллельного приложения. Мы их обсудим ниже. Но и Lynnfield`у не просто приблизиться к максимуму, для многих задач четырехкомпонентный SSE трудно применить, а «мягкая» модель параллельного исполнения одной инструкции 32 нитями CUDA прекрасно работает. Потому, что каждая нить CUDA-программы имеет прямой естественный доступ к своим данным, а работать с каждым элементом SSE-вектора в отдельности, непросто. И мелкие дивергенции нитей не оказывают заметного влияния на скорость. И не все программы вообще используют SSE, могут производить смешанные вычисления, но прекрасно распараллеливаемые в рамках CUDA-модели.
____Потому, что модель SIMT (single instruction multiple thread — «одна инструкция, много нитей») гораздо гибче, чем SIMD (single instruction multiple data — «одна инструкция, много данных»), так как в SIMT, эта инструкция может быть любой и в первую очередь — условным переходом. А в SIMD, если что-то случилось с одним элементом данных, который требует специальной обработки, вся параллельность пропадает и очень непросто эффективно программировать такие случаи.
____Надо отметить, что и той, и другой системе, для приближения к максимуму, нужна высокая степень параллельности. И если программа эффективно использует SSE и многопоточность, то велики шансы, что она хорошо совместится с архитектурой CUDA. Потому, что два, из трех главных требований к эффективной CUDA-программе, уже частично выполнено: параллелизм на уровне потоков и на уровне инструкций. Остается только решить проблему с памятью. А без SSE, теоретический максимум Lynnfield`а уменьшится в 4 раза, но и вероятные, в такой не поддающейся SSE-оптимизации программе, дивергентные ветвления могут существенно уменьшить скорость CUDA-варианта. Может в 7 раз, а может в 3.
____Уже примерный анализ теоретического максимума показывает некоторую бессмысленность его подсчета. Алгоритм может хорошо подойти высокопараллельной CUDA-архитектуре и тогда GPU выиграет с явным преимуществом в данной задаче. А в других случаях, можно получить не столь существенный прирост, не стоящий возни с технологией. Максимум скорее даёт оценку, что можно ожидать от CUDA в лучшем случае. Но необходимо помнить, что использовать несколько GPU значительно дешевле, чем системы на CPU. Как известно, многопроцессорные системы — уже другой рынок с другими ценами. Даже если GT200 равен по производительности Lynnfield, можно легко собрать систему с четырьмя GT200 на одной плате, а вот систему с четырьмя CPU купить — это гораздо более ответственный шаг.
____Так как CUDA-архитектура предназначена, в первую очередь для вычислений, а CPU универсальны, они выполняют множество серверных задач, для которых стоимость решения — не самый важный параметр, особенно по сравнению с совместимостью. Просто перекомпилировать многие приложения дороже, чем купить новую систему. А не то, что портировать. Но их обязательно надо исполнять и, с ростом бизнеса, потребности увеличиваются. Такой спрос на CPU автоматически удорожает их, по сравнению со специализированными устройствами.
____Представьте, вы покупаете танк и вам предлагают модель, обитую изнутри дорогой обшивкой со стразами. Конечно, такая машина будет стоить дороже сходного по боевым возможностям обычного танка. Всякие олигархи захотят купить гламурный танк, и поднимут цену. А важно ли это, для боевого применения?
Конец 2 части.
Параллельные вычислительные процессоры NVIDIA: настоящее и будущее, часть 2.
Содержание 2 части:
Память
Локальная память
Регистры и инструкции
Программная модель
Компилирование
Сравнительная производительность
Память.
____Память, в текущих CUDA-устройствах, находится на отдельных микросхемах на видеоплате, как системная память на системной. Поэтому, время доступа к ней исчисляется несколькими сотнями тактов. Но, имея сотни исполняющихся нитей, можно частично скрыть эту латентность, все равно в один момент может исполняться только группа из 32 нитей. Остальные пока подождут данных. Таким образом, можно сэкономить на размерах различных кэшей и, вместо памяти, на кристалле разместить ещё больше исполнительных устройств. Вот в этом проявляется использование существенной многопоточности алгоритма.
____Также, есть одна специальная возможность, доставшаяся от далеких предков: это доступная только для чтения текстурная память, которая читается при помощи текстурных блоков. Она имеет небольшой кэш 6–8 Кб на мультипроцессор и общий L2-кэш 256 Кб на всё устройство. С её помощью, можно ускорить доступ к немодифицируемым, в процессе работы программы, данным. Можно сказать, исходным данным. Текстурные кэши оптимизированы для двумерных массивов, что предоставляет неплохую оптимизационную возможность для приложений, которые работают с данными такого типа, изображениями например.
Локальная память.
____Но всё же, латентность глобальной памяти очень велика, её легче скрыть, если она читается по такой схеме: последовательно читаются данные, они обрабатываются и в глобальную память пишется результат.
____Но часто бывает, что нужно хранить большой объем промежуточных вычислений. Для этого существует локальная память мультипроцессора, которая в CUDA-терминологии называется разделяемой (shared). Потому, что она общая для всех нитей одного блока. Да, нити объединяются в блоки, это задается программистом при запуске программы. В отличие от размера варпа, равного 32 нитям и задаваемого требованиями железа, размер блока может варьироваться. Для простоты изложения концепции можно было бы считать, что в один момент мультипроцессор может исполнять один блок, состоящий из 1024 нитей, который обладает всей локальной памятью мультипроцессора, которая вся целиком доступна каждой нити блока. Но в реальности, размер блока может быть любым, в пределах 512 нитей и кратным размеру варпа, и мультипроцессор может одновременно выполнять несколько блоков, и память мультипроцессора, в этом случае, делится поровну между этими блоками.
____Размер этой памяти составляет всего 16 Кб. Но это соизмеримо с размером кэша данных первого уровня современных процессоров, средняя скорость доступа к ней довольно высока и составляет несколько тактов.
____Таким образом, CUDA-программа может работать с памятью по одной из двух схем: либо читать и писать всё в глобальную память, надеясь на то, что количество потоков, в значительной мере скроет латентность, либо разбить данные задачи на куски и последовательно помещать их в локальную память для обработки.
____Первый вариант оправдан, если программа перенасыщена вычислениями и читает, а также пишет в память относительно редко. Второй вариант предпочтительнее, он позволяет достичь близкой, к теоретическому максимуму, производительности, но не всегда возможен. Но первый легко программировать, не требуется специальной оптимизации. Возможна и комбинация двух подходов.
____Также есть общая для всех нитей, доступная только для чтения, память программных констант, размером 64 Кб, с быстрым доступом. У каждого мультипроцессора есть 8 Кб специального кэша для констант.
Регистры и инструкции.
____Помимо разделяемой памяти блока и общей глобальной памяти, каждой нити доступны собственно её регистры. Типичное их количество — 32 обычных 32-битных регистров. Точное количество регистров задаётся программистом, от этого зависит максимальное количество нитей, выполняющихся на мультипроцессоре, поскольку каждый мультипроцессор имеет банк из 16384 регистров, которые делятся между нитями.
____И опять, благодаря большому количеству нитей на мультипроцессоре, можно полностью скрыть латентность доступа к файлу регистров и иметь много регистров. Сама же ISA вполне обычна, это очень стандартный, простой и компактный, так называемый скалярный RISC с некоторыми важными ограничениями: GT200 не поддерживает С++, то есть, нет виртуальных функций и нет рекурсивных функций. Потому, что нет стека, всё на регистрах. Для вычислительных задач это непринципиальный момент, всё равно, в главных вычислительных циклах нельзя пользоваться виртуальными функциями, а рекурсивный алгоритм можно изменить так, чтобы не было вызова функций.
____Широко используются предикатные регистры, то есть значение регистра устанавливается в зависимости от значения логического выражения, вроде (a>b), которое либо истина, либо ложь. И далее, в коде следующей инструкции, например, перехода, задаётся, при каком значении какого предикатного регистра она выполняется. Так, переход становится условным. Очень удобно, на самом деле, и для компиляторов, и для ручного кодирования.
Программная модель.
____Что нужно сделать, чтобы запустить CUDA-программу? Надо загрузить исходные данные в память CUDA-устройства и запустить саму исполняемую функцию, указав ей количество нитей в блоке и общее количество блоков. Каждая из тысяч нитей прочитает в системной переменной свой номер, в соответствии с ним — свои данные для работы и запишет в соответствующую область памяти результат.
____Самый простой пример: нужно вычислить некую математическую функцию f от массива значений из 128 000 элементов. Мы загружаем этот массив элементов в память устройства, запускаем программу, её код инструкций система загружает на все мультипроцессоры. При запуске мы указываем, например, размер блока 128 нитей, а количество блоков 1000. Каждый мультипроцессор обрабатывает 8 блоков из 128 нитей, каждая нить читает, в соответствии со своим номером, элемент массива чисел, вычисляет функцию и записывает обратно. По мере выполнения всех нитей блока, мультипроцессор загружает на выполнение новые блоки. И далее, мы читаем данные из устройства обратно.
____Это самый простой пример, но сразу можно сказать, что производительность его, в первую очередь, зависит от того, сколько серьезных ветвлений есть в алгоритме функции f, насколько путь исполнения зависит от значений аргумента. Если сильно дивергентных, то есть по-разному исполняющихся в зависимости от аргумента, ветвлений мало, то производительность будет очень большой.
____Но нити не обязаны исполняться совсем независимо друг от друга. Для нитей внутри одного блока (это примерно 256 нитей), есть стандартные инструкции синхронизации исполнения Wait — ждать, когда все нити синхронизируются. Напомню, что нити абсолютно произвольны в своем поведении и совсем не похожи на SSE-инструкции. Есть так же инструкции атомарной записи данных в память блока, для обмена данными между нитями.
____То есть, нити в одном блоке могут переплетаться между собой. А вот блоки, в рамках CUDA-идеологии, предполагаются более независимыми. Они как будто бы исполняются на разных, далеко друг от друга расположенных, кластерах одного большого суперкомпьютера. Каждый из этих кластеров получил свое задание и, в каком порядке они исполняются, программисту неизвестно. Но некоторую синхронизацию, в частных случаях, можно организовать с помощью флагов в глобальной памяти. Например, организовать счетчик выполнения и старта блоков и, в зависимости от номера, блок будет выполнять свою часть задачи. Например, последний исполняющийся блок узнает, что он последний и может выполнить специальный завершающий этап работы. Или можно запустить новую программу, новый этап вычислений, который воспользуется сохраненными в памяти GPU результатами работы предыдущей программы.
Компилирование.
____На практике, принципиальная схема создания CUDA-программы такова: поставляемый NVIDIA компилятор встраивается в среду разработки, он компилирует исходный файл с кодом функции, которая должна исполняться на устройстве и превращает его в ассемблерный код для CUDA-устройства, который присоединяется к программе, как ресурс данных. При запуске программы на конкретной системе, этот код, с помощью библиотечной функции, передаётся видеодрайверу, который компилирует его для имеющегося CUDA-устройства в машинный код, специфичный для данного устройства. Так обеспечивается совместимость между редакциями архитектур. И далее, с помощью вызова библиотечных функций из кода основной программы, данные загружаются в GPU и для исполнения на устройстве вызывается скомпилированная драйвером функция.
____Можно также, на этапе компилирования, дополнительно создать несколько вариантов машинного кода для различных типов CUDA-GPU. Тогда драйвер, при запуске программы, может не компилировать ассемблерный код в машинный, а взять уже готовый вариант, если он существует для данного GPU. А если его нет (например, этот GPU ещё не вышел в момент написания программы), то будет компилироваться универсальный ассемблерный код.
Сравнительная производительность.
____Итак, мы ознакомились с главными моментами архитектуры CUDA, но смысл её существования в дополнительной производительности. Что можно, на данный момент, ожидать от присутствующих на рынке CUDA-устройств? Для сравнения с тридцатью мультипроцессорами архитектуры GT200, возьмём четырехъядерные Lynnfield вдвое большей частоты и сделаем, для начала, самую грубую оценку теоретического максимума в вычислениях, с вещественными числами одинарной точности. Как раз, у наиболее массовых моделей Lynnfield, частота примерно вдове выше массовых моделей GT200.
____GT200, за такт, теоретически выполняет 8*30=240 инструкций, а одно ядро Lynnfield, за два такта (что соответствует одному такту GT200), начинает выполнение четырех SSE-инструкций с 4 парами float-переменных. Таким образом, получается 4 ядра*2 такта*2 инструкции*4 переменных=64 инструкции.
____В теории, GT200 может быть примерно в 5 раз быстрее. Кстати, GT200 может за тот же свой такт выполнять инструкцию mul–add, умножения двух операндов и сложения с третьим. Если её посчитать, то в теории и в 10. Но на самом деле, для большинства задач, разница в этом моменте в 2 раза, что является мелочью, ничего бы не изменилось в этом мире, если бы GT200 не умел выполнять mul–add.
____Но на практике, все может обернуться самым разным образом. И тот, и другой теоретический максимум, не так легко, на самом деле, достичь. В архитектуре нынешних GPU есть несколько темных углов, которые могут убить реальную производительность, даже теоретически полностью параллельного приложения. Мы их обсудим ниже. Но и Lynnfield`у не просто приблизиться к максимуму, для многих задач четырехкомпонентный SSE трудно применить, а «мягкая» модель параллельного исполнения одной инструкции 32 нитями CUDA прекрасно работает. Потому, что каждая нить CUDA-программы имеет прямой естественный доступ к своим данным, а работать с каждым элементом SSE-вектора в отдельности, непросто. И мелкие дивергенции нитей не оказывают заметного влияния на скорость. И не все программы вообще используют SSE, могут производить смешанные вычисления, но прекрасно распараллеливаемые в рамках CUDA-модели.
____Потому, что модель SIMT (single instruction multiple thread — «одна инструкция, много нитей») гораздо гибче, чем SIMD (single instruction multiple data — «одна инструкция, много данных»), так как в SIMT, эта инструкция может быть любой и в первую очередь — условным переходом. А в SIMD, если что-то случилось с одним элементом данных, который требует специальной обработки, вся параллельность пропадает и очень непросто эффективно программировать такие случаи.
____Надо отметить, что и той, и другой системе, для приближения к максимуму, нужна высокая степень параллельности. И если программа эффективно использует SSE и многопоточность, то велики шансы, что она хорошо совместится с архитектурой CUDA. Потому, что два, из трех главных требований к эффективной CUDA-программе, уже частично выполнено: параллелизм на уровне потоков и на уровне инструкций. Остается только решить проблему с памятью. А без SSE, теоретический максимум Lynnfield`а уменьшится в 4 раза, но и вероятные, в такой не поддающейся SSE-оптимизации программе, дивергентные ветвления могут существенно уменьшить скорость CUDA-варианта. Может в 7 раз, а может в 3.
____Уже примерный анализ теоретического максимума показывает некоторую бессмысленность его подсчета. Алгоритм может хорошо подойти высокопараллельной CUDA-архитектуре и тогда GPU выиграет с явным преимуществом в данной задаче. А в других случаях, можно получить не столь существенный прирост, не стоящий возни с технологией. Максимум скорее даёт оценку, что можно ожидать от CUDA в лучшем случае. Но необходимо помнить, что использовать несколько GPU значительно дешевле, чем системы на CPU. Как известно, многопроцессорные системы — уже другой рынок с другими ценами. Даже если GT200 равен по производительности Lynnfield, можно легко собрать систему с четырьмя GT200 на одной плате, а вот систему с четырьмя CPU купить — это гораздо более ответственный шаг.
____Так как CUDA-архитектура предназначена, в первую очередь для вычислений, а CPU универсальны, они выполняют множество серверных задач, для которых стоимость решения — не самый важный параметр, особенно по сравнению с совместимостью. Просто перекомпилировать многие приложения дороже, чем купить новую систему. А не то, что портировать. Но их обязательно надо исполнять и, с ростом бизнеса, потребности увеличиваются. Такой спрос на CPU автоматически удорожает их, по сравнению со специализированными устройствами.
____Представьте, вы покупаете танк и вам предлагают модель, обитую изнутри дорогой обшивкой со стразами. Конечно, такая машина будет стоить дороже сходного по боевым возможностям обычного танка. Всякие олигархи захотят купить гламурный танк, и поднимут цену. А важно ли это, для боевого применения?
Конец 2 части.
Viktor2312- RIP
- Сообщения : 15492
Дата регистрации : 2012-08-10
Возраст : 45
Откуда : Пятигорск
.
3
.
Содержание 3 части:
«Тёмные углы»
Оптимизация
____По мнению автора, сама программная модель CUDA, особенно после того, как туда были добавлены примитивы для атомарной записи в память, необходимые для синхронизации потоков, вполне хороша в своём классе специализированных вычислительных архитектур и завершена. Но в текущей реализации в железе, есть несколько нетривиальных тонких моментов, требующих особого внимания разработчика и пренебрежение ими может существенно снизить производительность некоторых программ. В первую очередь, это так называемый совмещённый доступ к памяти. Когда нити одного варпа или полуварпа осуществляют общую операцию чтения данных из глобальной памяти, они все должны читать данные из одного 128-байтного участка, иначе одна транзакция разобьется на множество мелких. Должна соблюдаться жёсткая локальность данных внутри полуварпа и надо за этим специально следить. Иначе, программа будет слишком долго ждать данные от множества запросов на чтение. То же самое относится и к записи данных.
____В архитектуре традиционных CPU, такую проблему значительно уменьшают кэши. И латентность самой памяти несколько меньше. В CUDA же, призвано на помощь большое количество активных нитей на устройстве, но при совсем нелокальном чтении всех нитей и это не спасает. Тут, кстати, и дивергентные нити плохо себя проявляют, так как если все нити читают одновременно, то это одна транзакция, а если они выполняются последовательно и, таким образом, читают последовательно, то очень дорогостоящих операций обращения к памяти будет больше.
____В ранних CUDA-устройствах, эта проблема стояла ещё более остро, нити должны были читать данные последовательно, первая нить в варпе — начальный адрес, вторая нить — последующий и так далее. В последнем, на данный момент, графическом процессоре GT200, это ограничение снято.
____Момент совмещённой записи требует обязательной оптимизации приложения, которое часто читает из памяти, и сильно снижает эффективность CUDA на классе задач с частым нелокальным доступом к памяти. Когда количество вычислений соизмеримо с количеством обращений к памяти. Но если операции доступа к памяти довольно редки, то большое количество одновременно выполняющихся на мультипроцессоре нитей прекрасно скроет латентность памяти.
____Это лишний раз показывает бессмысленность сравнения теоретического максимума скорости GPU и CPU. И для приложений, интенсивно работающих с памятью, очень желательно разбить данные на блоки и поместить во внутреннюю память мультипроцессора.
____В случае доступа к 32-битным данным, память представляется разделенной на сегменты по 128 байт и если все нити полуварпа читают или пишут из одного сегмента, то осуществляется всего одна транзакция памяти.
____Когда нити варпа читают из различных сегментов, осуществляется несколько, в данном случае 5, дорогостоящих обращений к памяти.
____Вторая проблема связана с разделяемой памятью, расположенной на мультипроцессоре. Она разделена на 16 банков, как таблица на 16 колонок. И нити осуществляют операции доступа к ней по 16 штук за раз. То есть, сначала первая половина из 32 нитей варпа, исполняющего инструкцию доступа к разделяемой памяти блока, а потом вторая.
____И для максимальной производительности желательно, чтобы каждая нить читала данные из отдельной, собственной колонки. Не было такого, чтобы две нити запрашивали одну колонку. Такие запросы выполняются последовательно, что несколько снижает скорость доступа к локальной памяти мультипроцессора. Потому, что у каждой колонки свой порт и он не может в один момент обслужить две нити. Это не так страшно, как нелокальный доступ к глобальной памяти, но при активном использовании разделяемой памяти может привести к серьезным потерям производительности, это тоже лучше учитывать.
____Чтобы это обойти, может понадобиться немного изменить распределение памяти, например, вставить пустые ячейки, чтобы реальные данные раскидались по различным колонкам. Допустим, что все нити читают одну колонку, а если вставить одну пустую ячейку, то колонка превратится в диагональную лесенку и каждая нить сможет читать из различной колонки через свой порт, с полной производительностью.
____Разделяемая память мультипроцессора разделена на 16 банков, которые чередуются по адресам. Представлен случай оптимального доступа, каждая нить из полуварпа читает из своего банка. Номер в таблице показывает, из какой ячейки читает нить с соответствующим номером.
____Неоптимальный случай, все нити полуварпа читают из разных ячеек одного банка и запросы выполняются последовательно, что в N раз медленней. Правда, случай, когда все нити полуварпа читают из одной ячейки разделяемой памяти, оптимизирован. Её значение передается сразу всем нитям и потери скорости не происходит.
____Но всё равно, если нелокальность глобальной памяти может снизить скорость в несколько раз, то конфликты банков в разделяемой памяти — лишь на несколько десятков процентов, в случае интенсивного использования. Потому, что это проблемы разного уровня, доступ к внешним устройствам всегда на порядки затратнее, чем любые внутри кристалла коммуникации. Надо отметить, что различные варпы, даже полуварпы, составляющие один варп, уже полностью свободны и не связанны никакими ограничениями. Кстати, скорость передачи данных, собственно, от CPU до GPU "космически" медленная, по сравнению со скоростью вычислений. Проблема не только в пропускной способности, но и в латентности запуска процедуры копирования данных. И из GPU они идут по текущим интерфейсам на порядок медленней. Поэтому, CUDA-программу не имеет смысла вызывать, так сказать, по пустякам. Время её работы может оказаться мало, по сравнению с потерями на передачу данных и инициализацией системы и, никакого прироста не будет, даже если GPU все посчитает в 100 раз быстрее.
____Есть ещё один темноватый угол — это ограниченность объема памяти на видеоплате в несколько гигабайт, когда в рабочую станцию на базе CPU можно поставить в несколько раз больше. Но, все же это не самый принципиальный момент, для параллельной программы почти всегда можно разделить больший объем на куски, по нескольку гигабайт.
____Собственно, на этом почти всё. Остальные углы менее тёмные. Эти аспекты очень хорошо продемонстрированы на примере программы транспонирования матриц из CUDA SDK, когда скорость возрастает в разы при каждой оптимизации. Небольшая модификация кода влечет значительное изменение производительности. Но пример слишком страшный и приведена очень простая задача, для CPU тоже можно такой привести, а в более сложном приложении, скорость сглаживается.
____Если алгоритм не очень критичен к вышеупомянутым ограничениям памяти, или может быть изменён в соответствии с требованиями оптимального доступа, то можно ожидать великолепного прироста. Среди вышеупомянутого класса счётных задач есть множество таких, которые допускают реализацию CUDA оптимальным алгоритмом.
____Вопрос об использовании CUDA возникает, когда требуется увеличить производительность. И это сразу поднимает тему оптимизации программы. Ведь это первый способ ускорения работы. Скорость выполнения оптимизированной и не оптимизированной программы на обычном, современном CPU, может отличаться в десятки раз. Использование многоядерности и SIMD может дать прирост в 16 раз, а оптимизация доступа к памяти ещё в несколько раз.
____Оптимизация для CUDA состоит из двух взаимосвязанных этапов, надо выбрать подходящий и удобный для CUDA алгоритм решения требуемой задачи. Хорошо распараллеливающийся, естественно. Здесь надо отбросить все стереотипы мышления. Хороший алгоритм тот, который обеспечивает максимальную скорость с учётом данного железа. Вот образный пример: предположим, вы бизнес-леди и вам надо послать мужа за покупками. Вы пишете список, что купить, и муж отправляется обходить магазины, чтобы купить предметы по списку. А представьте, у вас целый гарем мужей и вы каждого отправляете в разные магазины с одним списком. Мужья не взаимодействуют между собой и принесут все товары, какие смогут купить. Разные мужья могут купить одинаковые вещи, ну и что, денег-то всё равно навалом. Зато вы получите всё, что вам нужно, гораздо быстрее, чем один, даже очень быстрый муж, оббегает множество магазинов.
____Впрочем, в новой версии CUDA, которую мы рассмотрим чуть позже, по заявкам наиболее жадных западных бизнес-леди, мужьям ещё купили мобильные телефоны. Чтобы они могли больше переговариваться между собой и не покупать лишнего.
____Алгоритм решения задачи надо выбирать, чтобы он по возможности обходил «тёмные углы» и вы точно получите значительный прирост. А при адаптации существующего алгоритма, надо в первую очередь обратить внимание на взаимодействие с памятью. Это ключевой момент, потому что вычислительная скорость несоизмерима с латентностью доступа к данным. Оптимизация уже имеющегося алгоритма, для CUDA, похожа на оптимизацию для классического CPU, только всё гораздо более сильно выражено. Как эффекты от оптимизации, так и провалы производительности при её полном отсутствии.
____При оптимизации для классического процессора, тоже очень полезно (и так часто делается) разбить данные на блоки, которые помещаются целиком в L1-кэш и там с ними работать. Для CUDA это часто обязательно, но и даёт больший прирост. Современные процессоры так же страдают от нелокального доступа к памяти, прячутся за колоссальными кэшами и так далее. Для CPU очень полезно применить SIMD, это даст прирост в несколько раз. Это же верно и для CUDA, причём применить благодаря мягкой модели SIMT гораздо проще, а эффект гораздо выше. Оптимизация для CUDA поднимает размер банка в несколько раз, при сравнимой ставке.
Конец 3 части.
Параллельные вычислительные процессоры NVIDIA: настоящее и будущее, часть 3.
Содержание 3 части:
«Тёмные углы»
Оптимизация
«Тёмные углы».
____По мнению автора, сама программная модель CUDA, особенно после того, как туда были добавлены примитивы для атомарной записи в память, необходимые для синхронизации потоков, вполне хороша в своём классе специализированных вычислительных архитектур и завершена. Но в текущей реализации в железе, есть несколько нетривиальных тонких моментов, требующих особого внимания разработчика и пренебрежение ими может существенно снизить производительность некоторых программ. В первую очередь, это так называемый совмещённый доступ к памяти. Когда нити одного варпа или полуварпа осуществляют общую операцию чтения данных из глобальной памяти, они все должны читать данные из одного 128-байтного участка, иначе одна транзакция разобьется на множество мелких. Должна соблюдаться жёсткая локальность данных внутри полуварпа и надо за этим специально следить. Иначе, программа будет слишком долго ждать данные от множества запросов на чтение. То же самое относится и к записи данных.
____В архитектуре традиционных CPU, такую проблему значительно уменьшают кэши. И латентность самой памяти несколько меньше. В CUDA же, призвано на помощь большое количество активных нитей на устройстве, но при совсем нелокальном чтении всех нитей и это не спасает. Тут, кстати, и дивергентные нити плохо себя проявляют, так как если все нити читают одновременно, то это одна транзакция, а если они выполняются последовательно и, таким образом, читают последовательно, то очень дорогостоящих операций обращения к памяти будет больше.
____В ранних CUDA-устройствах, эта проблема стояла ещё более остро, нити должны были читать данные последовательно, первая нить в варпе — начальный адрес, вторая нить — последующий и так далее. В последнем, на данный момент, графическом процессоре GT200, это ограничение снято.
____Момент совмещённой записи требует обязательной оптимизации приложения, которое часто читает из памяти, и сильно снижает эффективность CUDA на классе задач с частым нелокальным доступом к памяти. Когда количество вычислений соизмеримо с количеством обращений к памяти. Но если операции доступа к памяти довольно редки, то большое количество одновременно выполняющихся на мультипроцессоре нитей прекрасно скроет латентность памяти.
____Это лишний раз показывает бессмысленность сравнения теоретического максимума скорости GPU и CPU. И для приложений, интенсивно работающих с памятью, очень желательно разбить данные на блоки и поместить во внутреннюю память мультипроцессора.
____В случае доступа к 32-битным данным, память представляется разделенной на сегменты по 128 байт и если все нити полуварпа читают или пишут из одного сегмента, то осуществляется всего одна транзакция памяти.
____Когда нити варпа читают из различных сегментов, осуществляется несколько, в данном случае 5, дорогостоящих обращений к памяти.
____Вторая проблема связана с разделяемой памятью, расположенной на мультипроцессоре. Она разделена на 16 банков, как таблица на 16 колонок. И нити осуществляют операции доступа к ней по 16 штук за раз. То есть, сначала первая половина из 32 нитей варпа, исполняющего инструкцию доступа к разделяемой памяти блока, а потом вторая.
____И для максимальной производительности желательно, чтобы каждая нить читала данные из отдельной, собственной колонки. Не было такого, чтобы две нити запрашивали одну колонку. Такие запросы выполняются последовательно, что несколько снижает скорость доступа к локальной памяти мультипроцессора. Потому, что у каждой колонки свой порт и он не может в один момент обслужить две нити. Это не так страшно, как нелокальный доступ к глобальной памяти, но при активном использовании разделяемой памяти может привести к серьезным потерям производительности, это тоже лучше учитывать.
____Чтобы это обойти, может понадобиться немного изменить распределение памяти, например, вставить пустые ячейки, чтобы реальные данные раскидались по различным колонкам. Допустим, что все нити читают одну колонку, а если вставить одну пустую ячейку, то колонка превратится в диагональную лесенку и каждая нить сможет читать из различной колонки через свой порт, с полной производительностью.
____Разделяемая память мультипроцессора разделена на 16 банков, которые чередуются по адресам. Представлен случай оптимального доступа, каждая нить из полуварпа читает из своего банка. Номер в таблице показывает, из какой ячейки читает нить с соответствующим номером.
____Неоптимальный случай, все нити полуварпа читают из разных ячеек одного банка и запросы выполняются последовательно, что в N раз медленней. Правда, случай, когда все нити полуварпа читают из одной ячейки разделяемой памяти, оптимизирован. Её значение передается сразу всем нитям и потери скорости не происходит.
____Но всё равно, если нелокальность глобальной памяти может снизить скорость в несколько раз, то конфликты банков в разделяемой памяти — лишь на несколько десятков процентов, в случае интенсивного использования. Потому, что это проблемы разного уровня, доступ к внешним устройствам всегда на порядки затратнее, чем любые внутри кристалла коммуникации. Надо отметить, что различные варпы, даже полуварпы, составляющие один варп, уже полностью свободны и не связанны никакими ограничениями. Кстати, скорость передачи данных, собственно, от CPU до GPU "космически" медленная, по сравнению со скоростью вычислений. Проблема не только в пропускной способности, но и в латентности запуска процедуры копирования данных. И из GPU они идут по текущим интерфейсам на порядок медленней. Поэтому, CUDA-программу не имеет смысла вызывать, так сказать, по пустякам. Время её работы может оказаться мало, по сравнению с потерями на передачу данных и инициализацией системы и, никакого прироста не будет, даже если GPU все посчитает в 100 раз быстрее.
____Есть ещё один темноватый угол — это ограниченность объема памяти на видеоплате в несколько гигабайт, когда в рабочую станцию на базе CPU можно поставить в несколько раз больше. Но, все же это не самый принципиальный момент, для параллельной программы почти всегда можно разделить больший объем на куски, по нескольку гигабайт.
____Собственно, на этом почти всё. Остальные углы менее тёмные. Эти аспекты очень хорошо продемонстрированы на примере программы транспонирования матриц из CUDA SDK, когда скорость возрастает в разы при каждой оптимизации. Небольшая модификация кода влечет значительное изменение производительности. Но пример слишком страшный и приведена очень простая задача, для CPU тоже можно такой привести, а в более сложном приложении, скорость сглаживается.
____Если алгоритм не очень критичен к вышеупомянутым ограничениям памяти, или может быть изменён в соответствии с требованиями оптимального доступа, то можно ожидать великолепного прироста. Среди вышеупомянутого класса счётных задач есть множество таких, которые допускают реализацию CUDA оптимальным алгоритмом.
Оптимизация.
____Вопрос об использовании CUDA возникает, когда требуется увеличить производительность. И это сразу поднимает тему оптимизации программы. Ведь это первый способ ускорения работы. Скорость выполнения оптимизированной и не оптимизированной программы на обычном, современном CPU, может отличаться в десятки раз. Использование многоядерности и SIMD может дать прирост в 16 раз, а оптимизация доступа к памяти ещё в несколько раз.
____Оптимизация для CUDA состоит из двух взаимосвязанных этапов, надо выбрать подходящий и удобный для CUDA алгоритм решения требуемой задачи. Хорошо распараллеливающийся, естественно. Здесь надо отбросить все стереотипы мышления. Хороший алгоритм тот, который обеспечивает максимальную скорость с учётом данного железа. Вот образный пример: предположим, вы бизнес-леди и вам надо послать мужа за покупками. Вы пишете список, что купить, и муж отправляется обходить магазины, чтобы купить предметы по списку. А представьте, у вас целый гарем мужей и вы каждого отправляете в разные магазины с одним списком. Мужья не взаимодействуют между собой и принесут все товары, какие смогут купить. Разные мужья могут купить одинаковые вещи, ну и что, денег-то всё равно навалом. Зато вы получите всё, что вам нужно, гораздо быстрее, чем один, даже очень быстрый муж, оббегает множество магазинов.
____Впрочем, в новой версии CUDA, которую мы рассмотрим чуть позже, по заявкам наиболее жадных западных бизнес-леди, мужьям ещё купили мобильные телефоны. Чтобы они могли больше переговариваться между собой и не покупать лишнего.
____Алгоритм решения задачи надо выбирать, чтобы он по возможности обходил «тёмные углы» и вы точно получите значительный прирост. А при адаптации существующего алгоритма, надо в первую очередь обратить внимание на взаимодействие с памятью. Это ключевой момент, потому что вычислительная скорость несоизмерима с латентностью доступа к данным. Оптимизация уже имеющегося алгоритма, для CUDA, похожа на оптимизацию для классического CPU, только всё гораздо более сильно выражено. Как эффекты от оптимизации, так и провалы производительности при её полном отсутствии.
____При оптимизации для классического процессора, тоже очень полезно (и так часто делается) разбить данные на блоки, которые помещаются целиком в L1-кэш и там с ними работать. Для CUDA это часто обязательно, но и даёт больший прирост. Современные процессоры так же страдают от нелокального доступа к памяти, прячутся за колоссальными кэшами и так далее. Для CPU очень полезно применить SIMD, это даст прирост в несколько раз. Это же верно и для CUDA, причём применить благодаря мягкой модели SIMT гораздо проще, а эффект гораздо выше. Оптимизация для CUDA поднимает размер банка в несколько раз, при сравнимой ставке.
Конец 3 части.
Viktor2312- RIP
- Сообщения : 15492
Дата регистрации : 2012-08-10
Возраст : 45
Откуда : Пятигорск
.
4
.
Содержание 4 части:
Альтернативные решения CPU
Проблемы CUDA
Революционная архитектура «Ферми»
ECC
____По объективным причинам, производительность CPU растёт медленно, т. к. на десктопе множество задач, которым не нужно много потоков и производители CPU делают двуядерные модели. Выпуск шести– и восьмиядерных моделей отнесен на конец следующего года (статья написана в 2010г.), причём, это будут модели верхнего ценового уровня. В конце следующего года, компания Intel планирует представить новую архитектуру Sandy Bridge, мэйнстрим-вариант — четырехъядерный процессор с частотой около 3,5 GHz и интегрированным графическим ядром. С некоторыми небольшими архитектурными улучшениями, он может быть примерно в полтора раза быстрее топовой модели Lynnfield. А ещё, у Sandy Bridge будет восьмиэлементный SIMD набор AVX. Все SSE-программы придётся переписывать для новых размеров векторов. Но увеличение размера вектора до 8, это какой-то неясный путь, непонятна его перспектива. Потом до 16? Потом до 32? Модель SIMT из CUDA гораздо удобнее в программировании, это просто программирование на языке высокого уровня, без всяких дополнительных громоздких векторных инструкций.
____А если рассмотреть Larrabee, у которого вообще планировались шестнадцатиэлементные вектора? Ещё менее гибко и менее удобно. Такие длинные вектора мало где применимы, практически всегда требуется очень сложная оптимизация: как-то переставлять элементы, обрабатывать специальные случаи, когда нужно что-то сделать только с частью вектора. В этом смысле, даже сложная оптимизация под CUDA, более естественна для не узкоспециализированных программистов, для учёных, например. Она более алгоритмическая. Выбрать из множества алгоритмов с наибольшей локальностью обращений к памяти. Придумать, как разделить область задачи и как распараллелить её на тысячу потоков. Фишки AVX и архитектуры Larrabee ориентированы на ускорение сегодняшних алгоритмов, путем оптимизации с помощью низкоуровневых векторных инструкций. Но у модели Ларраби, выпуск которой перенесли надолго, согласно доступной информации, всё равно была недостаточная производительность в 3D графике. Скорее всего, Intel многое переделает, поэтому о Larrabee говорить ещё рано.
____Что мешает распространению CUDA? Благодаря предоставляемой архитектурой CUDA, высокой производительности, технология нашла большое количество применений в самых различных областях. На сайте компании NVIDIA можно найти примеры как экспериментальных, так и коммерческих приложений. Но области применения остаются локальными, они выглядят изолированными озерами на материке современного ПО. Это не море и не океан. Или лучше сравнить CUDA-приложения со скалами, которые поднимаются из безбрежного океана программ и возвышаются над ним. Чем больше производительность, тем выше пик. Они появляются и растут, то тут, то там, но пока ещё целые пласты не поднялись над спокойной гладью воды и не сформировали землю.
____Надо сразу отмести приложения и расчёты, которые и так выполняются достаточно быстро на современных процессорах. С другой стороны, наиболее вычислительно требовательные из пользовательских задач — приложения компьютерной графики на PC — успешно решаются специальными ускорителями 3D-графики, которые по странному стечению обстоятельств имеют тот же адрес места жительства в компьютере, что и CUDA-устройство. Если бы не они, вся графика считалась бы сейчас на CUDA.
____О проблеме совместимости можно и не говорить. Сейчас многие наоборот согласились бы на двукратную потерю производительности, чтоб только какую-то старую программу перенести без проблем с одной платформы на другую.
____Но наиболее важная проблема для рынка персональных ПК, на взгляд автора, это отсутствие совместимой с CUDA технологии подобного уровня от компании AMD. Для коммерческих разработчиков важна поддержка всех систем. Не будут же они писать на коробках, что их ПО предназначено только для пользователей решений NVIDIA. Если бы CUDA была реализована, пусть даже с меньшей производительностью, в решениях AMD, то сейчас было бы гораздо больше инвестиций в CUDA-ПО.
____Но, буквально в последние месяцы, AMD объявила о поддержке окончательного варианта OpenCL. По мнению автора, это другая обертка CUDA-архитектуры, по сути, абсолютно то же самое, как если бы мы конфету завернули в другой фантик. Автор нашел у OpenCL и CUDA меньше отличий, чем у OpenGL и Direct3D, например. А многие игры поддерживают и OpenGL, и Direct3D и картинка практически не отличается. Даже больше, между текущей реализацией CUDA и OpenCL меньше различий, чем между некоторыми версиями DirectX. Основные отличия в синтаксисе. В OpenСL текстура называется Image, например. Так что, эта проблема совместимости решена, пусть даже если ОpenCL-драйвера будут вначале хуже по исполнению видеодрайверов ATI.
____Еще одна сфера применения — это профессиональные решения для предприятий и организаций, когда поставляется техника и специальное ПО под конкретную задачу. Это решения для конкретных заказчиков, они не имеют массового тиража. Но на западном рынке соотношение зарплат, тем более, квалифицированных программистов и цен аппаратного обеспечения, другое. Там чаще экономически выгоднее, при малых объемах поставок, просто купить процессоры той же производительности, но за более высокую цену, чем привлекать дополнительных разработчиков, тестеров и т. п. В этом смысле, нашими предприятиями технология может быть быстрее востребована.
____Другая проблема — это ещё не полная «обкатанность» технологии, она просто ещё молода. Например, проблема, что некоторые операционные системы Windows пытаются действовать как OS реального времени и норовят прервать исполнение CUDA-программы, если оно продолжается больше 5 секунд. Таким образом, OS Microsoft не может «достучаться» до GPU и пытается что-то сделать. Очень бредово звучит. И разработчикам приходиться обходить эту проблему с использованием специфического системного программирования для каждой операционной системы Microsoft.
____В последних версиях CUDA, SDK и компилятора, многие пожелания пользователей были учтены. В первую очередь, с точки зрения не аппаратной архитектуры, а программного интерфейса, поддержки различных операционных систем и сред программирования. У автора не было с последней версией SDK никаких проблем.
____И последнее — вожделенный для NVIDIA рынок высокопроизводительных вычислений HPC. И тут, главным препятствием является недостаточная производительность вычислений с вещественными числами, типа double с двойной точностью. Все рекорды скорости GPU поставлены при работе с числами одинарной точности или целыми 32-битными или 16-битными. Для вычислений double, в нынешних GPU доступно только одно исполнительное устройство, таким образом, максимальная теоретическая скорость в 8 раз меньше и сравнима со скоростью любого современного четырехъядерного процессора. Такая игра не стоит свеч.
____Конечно, многим физическим задачам не требуется двойная точность расчётов. Многие пользователи в области химии, электродинамики, биологии успешно применили CUDA и получили дешёвую производительность для своих задач. В конце концов, производители CPU выкинули поддержку более точного 80–битного типа long double, потому что его размер не очень им удобен. Но, double — это стандарт в индустрии, все к нему привыкли. В конце концов, редко система собирается ради одного алгоритма. А если он изменится, если потребуется считать что-то иное. Такая узкая специализация устройства препятствует широкому применению. И дополнительная скорость CUDA-устройства может быть не настолько востребована, чтобы проверять и исследовать, выдержит ли используемый алгоритм переход на вычисления с числами одинарной точности, не накопится ли где-нибудь погрешность. Или разрабатывать новый, специально для работы с float.
____Но отсутствие полной поддержки double не есть базовая черта архитектуры CUDA. Так сложилось, не будем говорить почему (подсказка, в графике тип double не очень востребован), что CUDA-устройства имеют исполнительные устройства, работающие с float. Если бы вместо 8 float-операций выполнялось 8 операций с вещественными числами двойной точности, уже сейчас применений CUDA в HPC было бы на порядок больше. И в новой версии CUDA-архитектуры, «Fermi», уже целенаправленно предназначенной для HPC и других «неграфических» применений, double поддерживается наравне со float, как и в обычных CPU. И является таким же базовым типом переменных.
____В новой архитектуре так много качественных улучшений, решающих большинство из вышеперечисленных проблем CUDA, что она претендует на статус революционной.
____Хорошо, что на свете не бывает чудес, иначе жизнь была бы слишком пресной и скучной. Если бы микросхемы, на основе представленной в начале октября архитектуре, появились прямо сейчас, по типичным ценам и объёмам, это было бы чудо, настолько она продвинута на данный момент. Но проблемы с переходом на новый техпроцесс, которые случаются, время от времени, со всеми производителями микросхем, задерживают выпуск продукта.
____Это не так принципиально для разработки, так как существующим CUDA-программам не потребуется переделки, чтобы воспользоваться преимуществами новой архитектуры. Для полного ускорения может потребоваться некоторая переконфигурация, изменение количества нитей в блоке и размера разделяемой памяти блока. Но практически все CUDA-программы могут свободно варьировать эти параметры. Потому, что несколько всё равно: что 128, что 256, что 512 нитей. И у разработчиков появится время, чтобы подготовить продукты к анонсу, с расчетом на его уже новые возможности. Зачем нужна микросхема, если для неё нет программ?
____У новой микросхемы нет пока имени и я придумал назвать его «Reflection» («Отражение»), потому что в новой архитектуре отражено огромное количество пожеланий авторов CUDA-программ. И он «отражает» критику слабых мест прежней архитектуры. И те, кто знаком с компьютерной графикой знает, что эффекты рендерятся долго и его применение как раз ускорит отрисовку таких сложных визуальных эффектов.
____Самое главное для HPC–устремлений NVIDIA, новая микросхема полноценно поддерживает double. Каким образом это достигнуто? В новой архитектуре мультипроцессоры стали более «жирными». Вместо 8 исполнительных устройств, их стало 32. И, по-видимому, два соседних устройства вычисляют, вместо пары float-операций, одну double. Производительность в double просто в два раза меньше, чем во float. Либо 32 операции с числами с одинарной точностью, либо 16 с двойной. Это в точности как в SSE обычных CPU, производительность в double в два раза ниже. Количество мультипроцессоров уменьшилось до 16, но общее количество операций возросло более чем вдвое, а с double–числами почти на порядок.
____Так представляет новую микросхему NVIDIA. 16 мультипроцессоров с 32 исполнительными устройствами, обозначенными зелеными прямоугольниками. 4 вертикальных прямоугольника салатового цвета обозначают модули вычисления специальных функций, тригонометрических и корней. Небольшие зеленые квадратики, видимо, обозначают 16 устройств калькуляции адресов.
____Оранжевые прямоугольники обозначают «дуальный» планировщик и модуль dispatch. Синие области обозначают L1-кэш с разделяемой памятью, блок регистров, который по некоторым сведениям удвоился и специальный кэш инструкций, подробности о функционировании которого не разглашаются.
____Если бы NVIDIA ограничилась только этим, то это был бы уже большой шаг вперёд. Но улучшения приняли тотальный характер.
____Точность float-вычислений тоже была повышена, в соответствии со спецификациями самого последнего стандарта. Включена поддержка денормализированных чисел с полной скоростью, что CPU делать не умеют. Денормализированные числа — это маленькие числа, на границе точности формата float.
____В результате, CUDA-устройство может считать точнее, чем CPU. Вполне очевидно, благодаря чему это стало возможно. Мультипроцессор работает на меньшей частоте, чем CPU, нет такой требовательности к дизайну модулей умножения, чтобы они работали на невероятной скорости и их можно совершенствовать «вширь». Этого изначально стоило ожидать от CUDA-архитектуры. Была бы потребность, можно было бы относительно легко и 128–битные вещественные числа сделать.
____Критики архитектуры CUDA справедливо указывали, что для применения в системах HPC требуется поддержка алгоритмов коррекции ошибок ECC, которые иногда возникают в электронных устройствах. Когда тысячи устройств работают круглые сутки, ошибки неизбежно появляются, время от времени. На это энтузиасты технологии отвечали, что преимущество в скорости CUDA так велико, что можно для проверки результата считать его два раза, особенно конечный. Но, как будто бы ECC каким-то образом противоречит самой идее CUDA-архитектуры? Конечно же нет, на низкочастотном устройстве её воплотить даже легче. И новая микросхема имеет полную поддержку технологий коррекции.
____На этом примере можно отметить, что многие претензии к CUDA носят поверхностный, непринципиальный характер. Их устранение можно с уверенностью ожидать в будущих релизах. Просто всё сразу невозможно сделать.
Конец 4 части.
Параллельные вычислительные процессоры NVIDIA: настоящее и будущее, часть 4.
Содержание 4 части:
Альтернативные решения CPU
Проблемы CUDA
Революционная архитектура «Ферми»
ECC
Альтернативные решения CPU.
____По объективным причинам, производительность CPU растёт медленно, т. к. на десктопе множество задач, которым не нужно много потоков и производители CPU делают двуядерные модели. Выпуск шести– и восьмиядерных моделей отнесен на конец следующего года (статья написана в 2010г.), причём, это будут модели верхнего ценового уровня. В конце следующего года, компания Intel планирует представить новую архитектуру Sandy Bridge, мэйнстрим-вариант — четырехъядерный процессор с частотой около 3,5 GHz и интегрированным графическим ядром. С некоторыми небольшими архитектурными улучшениями, он может быть примерно в полтора раза быстрее топовой модели Lynnfield. А ещё, у Sandy Bridge будет восьмиэлементный SIMD набор AVX. Все SSE-программы придётся переписывать для новых размеров векторов. Но увеличение размера вектора до 8, это какой-то неясный путь, непонятна его перспектива. Потом до 16? Потом до 32? Модель SIMT из CUDA гораздо удобнее в программировании, это просто программирование на языке высокого уровня, без всяких дополнительных громоздких векторных инструкций.
____А если рассмотреть Larrabee, у которого вообще планировались шестнадцатиэлементные вектора? Ещё менее гибко и менее удобно. Такие длинные вектора мало где применимы, практически всегда требуется очень сложная оптимизация: как-то переставлять элементы, обрабатывать специальные случаи, когда нужно что-то сделать только с частью вектора. В этом смысле, даже сложная оптимизация под CUDA, более естественна для не узкоспециализированных программистов, для учёных, например. Она более алгоритмическая. Выбрать из множества алгоритмов с наибольшей локальностью обращений к памяти. Придумать, как разделить область задачи и как распараллелить её на тысячу потоков. Фишки AVX и архитектуры Larrabee ориентированы на ускорение сегодняшних алгоритмов, путем оптимизации с помощью низкоуровневых векторных инструкций. Но у модели Ларраби, выпуск которой перенесли надолго, согласно доступной информации, всё равно была недостаточная производительность в 3D графике. Скорее всего, Intel многое переделает, поэтому о Larrabee говорить ещё рано.
Проблемы CUDA.
____Что мешает распространению CUDA? Благодаря предоставляемой архитектурой CUDA, высокой производительности, технология нашла большое количество применений в самых различных областях. На сайте компании NVIDIA можно найти примеры как экспериментальных, так и коммерческих приложений. Но области применения остаются локальными, они выглядят изолированными озерами на материке современного ПО. Это не море и не океан. Или лучше сравнить CUDA-приложения со скалами, которые поднимаются из безбрежного океана программ и возвышаются над ним. Чем больше производительность, тем выше пик. Они появляются и растут, то тут, то там, но пока ещё целые пласты не поднялись над спокойной гладью воды и не сформировали землю.
____Надо сразу отмести приложения и расчёты, которые и так выполняются достаточно быстро на современных процессорах. С другой стороны, наиболее вычислительно требовательные из пользовательских задач — приложения компьютерной графики на PC — успешно решаются специальными ускорителями 3D-графики, которые по странному стечению обстоятельств имеют тот же адрес места жительства в компьютере, что и CUDA-устройство. Если бы не они, вся графика считалась бы сейчас на CUDA.
____О проблеме совместимости можно и не говорить. Сейчас многие наоборот согласились бы на двукратную потерю производительности, чтоб только какую-то старую программу перенести без проблем с одной платформы на другую.
____Но наиболее важная проблема для рынка персональных ПК, на взгляд автора, это отсутствие совместимой с CUDA технологии подобного уровня от компании AMD. Для коммерческих разработчиков важна поддержка всех систем. Не будут же они писать на коробках, что их ПО предназначено только для пользователей решений NVIDIA. Если бы CUDA была реализована, пусть даже с меньшей производительностью, в решениях AMD, то сейчас было бы гораздо больше инвестиций в CUDA-ПО.
____Но, буквально в последние месяцы, AMD объявила о поддержке окончательного варианта OpenCL. По мнению автора, это другая обертка CUDA-архитектуры, по сути, абсолютно то же самое, как если бы мы конфету завернули в другой фантик. Автор нашел у OpenCL и CUDA меньше отличий, чем у OpenGL и Direct3D, например. А многие игры поддерживают и OpenGL, и Direct3D и картинка практически не отличается. Даже больше, между текущей реализацией CUDA и OpenCL меньше различий, чем между некоторыми версиями DirectX. Основные отличия в синтаксисе. В OpenСL текстура называется Image, например. Так что, эта проблема совместимости решена, пусть даже если ОpenCL-драйвера будут вначале хуже по исполнению видеодрайверов ATI.
____Еще одна сфера применения — это профессиональные решения для предприятий и организаций, когда поставляется техника и специальное ПО под конкретную задачу. Это решения для конкретных заказчиков, они не имеют массового тиража. Но на западном рынке соотношение зарплат, тем более, квалифицированных программистов и цен аппаратного обеспечения, другое. Там чаще экономически выгоднее, при малых объемах поставок, просто купить процессоры той же производительности, но за более высокую цену, чем привлекать дополнительных разработчиков, тестеров и т. п. В этом смысле, нашими предприятиями технология может быть быстрее востребована.
____Другая проблема — это ещё не полная «обкатанность» технологии, она просто ещё молода. Например, проблема, что некоторые операционные системы Windows пытаются действовать как OS реального времени и норовят прервать исполнение CUDA-программы, если оно продолжается больше 5 секунд. Таким образом, OS Microsoft не может «достучаться» до GPU и пытается что-то сделать. Очень бредово звучит. И разработчикам приходиться обходить эту проблему с использованием специфического системного программирования для каждой операционной системы Microsoft.
____В последних версиях CUDA, SDK и компилятора, многие пожелания пользователей были учтены. В первую очередь, с точки зрения не аппаратной архитектуры, а программного интерфейса, поддержки различных операционных систем и сред программирования. У автора не было с последней версией SDK никаких проблем.
____И последнее — вожделенный для NVIDIA рынок высокопроизводительных вычислений HPC. И тут, главным препятствием является недостаточная производительность вычислений с вещественными числами, типа double с двойной точностью. Все рекорды скорости GPU поставлены при работе с числами одинарной точности или целыми 32-битными или 16-битными. Для вычислений double, в нынешних GPU доступно только одно исполнительное устройство, таким образом, максимальная теоретическая скорость в 8 раз меньше и сравнима со скоростью любого современного четырехъядерного процессора. Такая игра не стоит свеч.
____Конечно, многим физическим задачам не требуется двойная точность расчётов. Многие пользователи в области химии, электродинамики, биологии успешно применили CUDA и получили дешёвую производительность для своих задач. В конце концов, производители CPU выкинули поддержку более точного 80–битного типа long double, потому что его размер не очень им удобен. Но, double — это стандарт в индустрии, все к нему привыкли. В конце концов, редко система собирается ради одного алгоритма. А если он изменится, если потребуется считать что-то иное. Такая узкая специализация устройства препятствует широкому применению. И дополнительная скорость CUDA-устройства может быть не настолько востребована, чтобы проверять и исследовать, выдержит ли используемый алгоритм переход на вычисления с числами одинарной точности, не накопится ли где-нибудь погрешность. Или разрабатывать новый, специально для работы с float.
____Но отсутствие полной поддержки double не есть базовая черта архитектуры CUDA. Так сложилось, не будем говорить почему (подсказка, в графике тип double не очень востребован), что CUDA-устройства имеют исполнительные устройства, работающие с float. Если бы вместо 8 float-операций выполнялось 8 операций с вещественными числами двойной точности, уже сейчас применений CUDA в HPC было бы на порядок больше. И в новой версии CUDA-архитектуры, «Fermi», уже целенаправленно предназначенной для HPC и других «неграфических» применений, double поддерживается наравне со float, как и в обычных CPU. И является таким же базовым типом переменных.
____В новой архитектуре так много качественных улучшений, решающих большинство из вышеперечисленных проблем CUDA, что она претендует на статус революционной.
Революционная архитектура «Ферми».
____Хорошо, что на свете не бывает чудес, иначе жизнь была бы слишком пресной и скучной. Если бы микросхемы, на основе представленной в начале октября архитектуре, появились прямо сейчас, по типичным ценам и объёмам, это было бы чудо, настолько она продвинута на данный момент. Но проблемы с переходом на новый техпроцесс, которые случаются, время от времени, со всеми производителями микросхем, задерживают выпуск продукта.
____Это не так принципиально для разработки, так как существующим CUDA-программам не потребуется переделки, чтобы воспользоваться преимуществами новой архитектуры. Для полного ускорения может потребоваться некоторая переконфигурация, изменение количества нитей в блоке и размера разделяемой памяти блока. Но практически все CUDA-программы могут свободно варьировать эти параметры. Потому, что несколько всё равно: что 128, что 256, что 512 нитей. И у разработчиков появится время, чтобы подготовить продукты к анонсу, с расчетом на его уже новые возможности. Зачем нужна микросхема, если для неё нет программ?
____У новой микросхемы нет пока имени и я придумал назвать его «Reflection» («Отражение»), потому что в новой архитектуре отражено огромное количество пожеланий авторов CUDA-программ. И он «отражает» критику слабых мест прежней архитектуры. И те, кто знаком с компьютерной графикой знает, что эффекты рендерятся долго и его применение как раз ускорит отрисовку таких сложных визуальных эффектов.
____Самое главное для HPC–устремлений NVIDIA, новая микросхема полноценно поддерживает double. Каким образом это достигнуто? В новой архитектуре мультипроцессоры стали более «жирными». Вместо 8 исполнительных устройств, их стало 32. И, по-видимому, два соседних устройства вычисляют, вместо пары float-операций, одну double. Производительность в double просто в два раза меньше, чем во float. Либо 32 операции с числами с одинарной точностью, либо 16 с двойной. Это в точности как в SSE обычных CPU, производительность в double в два раза ниже. Количество мультипроцессоров уменьшилось до 16, но общее количество операций возросло более чем вдвое, а с double–числами почти на порядок.
____Так представляет новую микросхему NVIDIA. 16 мультипроцессоров с 32 исполнительными устройствами, обозначенными зелеными прямоугольниками. 4 вертикальных прямоугольника салатового цвета обозначают модули вычисления специальных функций, тригонометрических и корней. Небольшие зеленые квадратики, видимо, обозначают 16 устройств калькуляции адресов.
____Оранжевые прямоугольники обозначают «дуальный» планировщик и модуль dispatch. Синие области обозначают L1-кэш с разделяемой памятью, блок регистров, который по некоторым сведениям удвоился и специальный кэш инструкций, подробности о функционировании которого не разглашаются.
____Если бы NVIDIA ограничилась только этим, то это был бы уже большой шаг вперёд. Но улучшения приняли тотальный характер.
____Точность float-вычислений тоже была повышена, в соответствии со спецификациями самого последнего стандарта. Включена поддержка денормализированных чисел с полной скоростью, что CPU делать не умеют. Денормализированные числа — это маленькие числа, на границе точности формата float.
____В результате, CUDA-устройство может считать точнее, чем CPU. Вполне очевидно, благодаря чему это стало возможно. Мультипроцессор работает на меньшей частоте, чем CPU, нет такой требовательности к дизайну модулей умножения, чтобы они работали на невероятной скорости и их можно совершенствовать «вширь». Этого изначально стоило ожидать от CUDA-архитектуры. Была бы потребность, можно было бы относительно легко и 128–битные вещественные числа сделать.
ECC.
____Критики архитектуры CUDA справедливо указывали, что для применения в системах HPC требуется поддержка алгоритмов коррекции ошибок ECC, которые иногда возникают в электронных устройствах. Когда тысячи устройств работают круглые сутки, ошибки неизбежно появляются, время от времени. На это энтузиасты технологии отвечали, что преимущество в скорости CUDA так велико, что можно для проверки результата считать его два раза, особенно конечный. Но, как будто бы ECC каким-то образом противоречит самой идее CUDA-архитектуры? Конечно же нет, на низкочастотном устройстве её воплотить даже легче. И новая микросхема имеет полную поддержку технологий коррекции.
____На этом примере можно отметить, что многие претензии к CUDA носят поверхностный, непринципиальный характер. Их устранение можно с уверенностью ожидать в будущих релизах. Просто всё сразу невозможно сделать.
Конец 4 части.
Viktor2312- RIP
- Сообщения : 15492
Дата регистрации : 2012-08-10
Возраст : 45
Откуда : Пятигорск
Re: Tesla. CUDA. Статьи.
5
.
Содержание 5 части:
Дуальный планировщик варпов
L1-кэш
L2–кэш
Поддержка C++
Программные улучшения
Заключение
Ссылки
____Как уже говорилось выше, в мультипроцессоре теперь 32 исполнительных устройства, которые в терминологии CUDA называются Scalar Processor Core, или CUDA Core. В процессорной терминологии, этому больше соответствует functional unit с небольшой оберткой. То есть, мультипроцессор может выполнить целый варп за такт. Но это неудобно, потому что остальная часть мультипроцессора работает на половинной частоте, по сравнению с частотой «скалярных процессорных ядер». Чтобы разрешить ситуацию, планировщик варпов был сделан двойным, он сразу отправляет на исполнение два варпа, каждый на 16 исполнительных устройств. Таким образом, варп из 32 одинаковых инструкций выполняется за два такта функциональных устройств и один такт остального ядра. Но два варпа, выполняющие инструкцию c данными типа double, не могут быть исполнены вместе, так как инструкции double выполняются два такта или двумя функциональными устройствами. То есть, так полный варп из 32 double-инструкций выполнится за один «длинный» такт.
____Не предполагается, что такая конструкция как-то поможет ускорить дивергентные ветвления внутри одного варпа. Просто варп с такими ветвлениями будет исполняться дольше, пропорционально количеству ветвлений, в то время как другие варпы будут идти параллельно.
____С применением нового техпроцесса, стало возможным увеличить размер локальной памяти мультипроцессора и сделать небольшой L1-кэш, а так же разместить на кристалле общий для всех мультипроцессоров L2-кэш размером 768 Кб.
____Является ли это отходом от подхода, реализованного в предыдущих графических процессорах, которые обходятся почти без кэшей? Может, лучше было и этот кэш пустить на мультипроцессоры? Нет, он занимает мало места, а пользы может принести много.
____Он служит, в первую очередь, для буферизации. Просто, даже если нить запрашивает из глобальной памяти 4 байта, транзакция всё равно осуществляется минимум с 64 байтами. И весьма вероятно, что загруженные данные могут понадобиться вскоре этой или другим нитям. Эти загруженные блоки данных можно пока сохранить. С такой логикой, раз уж мы скопировали из памяти избыточные данные, пока оставим, вдруг пригодятся.
____Теперь, размер локальной памяти мультипроцессора составляет 64 Кб и её можно сконфигурировать программно, оставить 16 Кб разделяемой и 48 Кб нового L1-кэша. Это полезно для старых CUDA-программ, которые не знают о том, что объём разделяемой памяти, доступной блоку нитей, увеличился. Зато они могут выиграть от большего размера кэша. Или сконфигурировать локальную память, в пропорции 48 Кб разделяемой, 16 Кб кэша. То есть, дать возможность программе самой решить, что загружать в память мультипроцессора. Но это тоже будет способствовать росту производительности старых CUDA-программ, так как большее количество блоков и нитей сможет одновременно выполняться на мультипроцессоре. Допустим, если раньше один блок из 256 нитей требовал 16 Кб разделяемой памяти и на мультипроцессоре мог выполняться только один блок, то сейчас — 3, так как им всем хватит памяти.
____Также, L1-кэш очень поможет для быстрого свопа, то есть, временного хранения регистров. Сейчас, при программировании CUDA-приложения, желательно использовать как можно меньше регистров мультипроцессора, чтобы на одном мультипроцессоре можно было запустить больше нитей. И, крайне нежелательно, временно сбрасывать содержимое регистров в медленную глобальную память. На это иногда жалуются CUDA-программисты, что им не хватает регистров. А если хватает, то запускается меньше нитей, которые меньше скрывают различные задержки. Приходится думать, как программу реализовать с меньшим количеством временных регистров. Интересная оптимизационная задача конечно. Немного необычно: найти такой нетребовательный алгоритм, иногда бывает похоже на задачу из олимпиады по информатике.
____Первая функция общего кэша второго уровня — это радикально ускорить и упростить синхронизацию всех исполняющихся нитей. Нити, выполняющейся на одном мультипроцессоре, не могут видеть содержимое L1–кэшей других мультипроцессоров, но когда данные сбрасываются в L2–кэш, например, принудительными синхронизирующими инструкциями, они сразу становятся видимыми для всех. Раньше, для синхронизации между блоками использовалась сверхмедленная, глобальная память. Это сильно упрощает написание сложных CUDA-программ.
____И, конечно, L2 выступает неким общим пулом загружаемых из глобальной памяти данных. GT200 имеет 256 Кб кэша второго уровня для текстурной памяти на все мультипроцессоры, сейчас размер кэша утроился до 768 Кб. И он стал полноценным, а не только для чтения данных.
____Удобно, конечно, для контроллеров памяти, оперирующих широкими кусками данных, наполнять строчки L1- ; L2-кэшей. Именно в ширине интерфейса глобальной памяти кроется необходимость иметь достаточно большой промежуточный пул и несколько отойти от концепции тратить всю площадь кристалла на исполнительные устройства. Представьте, вы заказываете из магазина товар, но в вашем распоряжении самосвал, он привозит не только товар, но и всё, что рядом лежит. Раньше оно выбрасывалось, а теперь сохраняется в кэше. И конечно, некоторые задачи с объёмом данных, сравнимым с размером кэша, получат очень сильный прирост. Но никакой кэш, тем более, меньше мегабайта размером, не решит проблему доступности данных в случае, близкого к случайному, доступа десятков тысяч одновременно исполняющихся на мультипроцессоре нитей. Для этой цели служит большое количество активных нитей на мультипроцессоре. Кстати, максимальное количество одновременно исполняющихся нитей на мультипроцессоре также возросло.
____Новая версия архитектуры CUDA включает полную поддержку C++, виртуальных функций, указателей на функции и конструкций try–catch. Это расширяет область применения решений на основе архитектуры Fermi и сильно облегчает портирование многих существующих приложений на GPU. Но главное, что многие программисты просто любят программировать на С++, даже если он не очень нужен для решения конкретной задачи. Очень характерно, что часто, обсуждение архитектуры «Ферми» моментально выливается в спор С vs С++. Чтож, скоро сторонники и противники разных подходов к программированию получат ещё одно поле битвы. На чем лучше программировать Fermi? С или С++?
____Но на языках Си свет клином не сошёлся и, благодаря поддержке указателей на функции, стала возможной поддержка большого количества самых разнообразных языков программирования. Причём, не ориентированных на высокую скорость исполнения написанных на них программ.
____Изначально, CUDA предназначалась для высокопроизводительных, во многом оптимизированных приложений, но многие программы выгоднее писать без оглядки на железо, а потом смотреть, как процессоры «страдают», выполняя тяжёлый код и выбирать лучшее для своей задачи. Параллельное программирование проникает в массы и, с полной поддержкой указателей, появилась возможность просто запускать на GPU широкий класс параллельных программ. Fermi и в этом случае может оказаться конкурентоспособным, т. к. такие программы и на классическом CPU будут отчаянно медленно исполняться. И на каждое обращение к памяти у них будет море инструкций обращения к собственным регистрам и так далее.
____Да, для универсализации потребовалось объединить в одном адресном пространстве всю, доступную отдельной нити, память. Собственную память мультипроцессора и видимую глобальную память. Это также важно для заявленной поддержки операторов new и delete, то есть, выделения памяти прямо из CUDA-программы, исполняющейся на CUDA-устройстве. О чём раньше и подумать было нельзя. Очень интересно будет посмотреть, как в реальности будет работать собственный менеджер памяти.
____Компания NVIDIA заявляет об увеличении скорости переключения задач, поскольку на GPU может выполняться несколько CUDA-приложений. Но более важно то, что теперь одновременно может выполняться несколько CUDA-функций одного приложения. Потому, что одна может не загрузить всё устройство. И это делает возможным плотнее загрузить поддерживающий CUDA GPU при запуске нескольких задач подряд. Так как программа, приближаясь к своему завершению, может работать лишь на нескольких мультипроцессорах, в то время как остальные уже освободились.
____Исполнение нескольких функций может помочь скрыть длительное время передачи данных по шине PCI-Express. Чтобы GPU не останавливался в ожидании передачи данных. Может быть, даже одну задачу выгодно будет делить на несколько меньших, чтобы первые блоки уже начинали считать, пока подгружаются остальные данные.
____Последний пункт особенно чётко демонстрирует «суперкомпьютерный» характер новой архитектуры. Можно смело сказать, что мы получаем настоящий суперкомпьютер на столе. Страшно подумать, что их ещё можно установить несколько в одной системе и объединить вместе несколько таких компьютеров. Получается целый вычислительный фрактал. Перечислим его: нить — полуварп (16) — варп (2*16) — блок нитей (2*16*8 ) — мультипроцессор (2*16*8*4) — GPU (2*16*8*4*30) — multiGPU (2*16*8*4*30*4) — узел из 8 компьютеров (2*16*8*4*30*4*8 )= ~ пол миллиона нитей и десять тысяч операций за одну миллиардную секунды. И дешевле обычного сервера.
____«Революционность» новой архитектуры заключается в том, что улучшения произошли как количественные, так и качественные. Теоретических гигафлопов стало намного больше, особенно в вычислениях с двойной точностью. Одновременно с этим, их стало гораздо легче получить, как с точки зрения улучшения аппаратного обеспечения, так и со стороны поддержки средств разработки.
Конец.
.
Параллельные вычислительные процессоры NVIDIA: настоящее и будущее, часть 5.
Содержание 5 части:
Дуальный планировщик варпов
L1-кэш
L2–кэш
Поддержка C++
Программные улучшения
Заключение
Ссылки
Дуальный планировщик варпов.
____Как уже говорилось выше, в мультипроцессоре теперь 32 исполнительных устройства, которые в терминологии CUDA называются Scalar Processor Core, или CUDA Core. В процессорной терминологии, этому больше соответствует functional unit с небольшой оберткой. То есть, мультипроцессор может выполнить целый варп за такт. Но это неудобно, потому что остальная часть мультипроцессора работает на половинной частоте, по сравнению с частотой «скалярных процессорных ядер». Чтобы разрешить ситуацию, планировщик варпов был сделан двойным, он сразу отправляет на исполнение два варпа, каждый на 16 исполнительных устройств. Таким образом, варп из 32 одинаковых инструкций выполняется за два такта функциональных устройств и один такт остального ядра. Но два варпа, выполняющие инструкцию c данными типа double, не могут быть исполнены вместе, так как инструкции double выполняются два такта или двумя функциональными устройствами. То есть, так полный варп из 32 double-инструкций выполнится за один «длинный» такт.
____Не предполагается, что такая конструкция как-то поможет ускорить дивергентные ветвления внутри одного варпа. Просто варп с такими ветвлениями будет исполняться дольше, пропорционально количеству ветвлений, в то время как другие варпы будут идти параллельно.
____С применением нового техпроцесса, стало возможным увеличить размер локальной памяти мультипроцессора и сделать небольшой L1-кэш, а так же разместить на кристалле общий для всех мультипроцессоров L2-кэш размером 768 Кб.
____Является ли это отходом от подхода, реализованного в предыдущих графических процессорах, которые обходятся почти без кэшей? Может, лучше было и этот кэш пустить на мультипроцессоры? Нет, он занимает мало места, а пользы может принести много.
L1-кэш.
____Он служит, в первую очередь, для буферизации. Просто, даже если нить запрашивает из глобальной памяти 4 байта, транзакция всё равно осуществляется минимум с 64 байтами. И весьма вероятно, что загруженные данные могут понадобиться вскоре этой или другим нитям. Эти загруженные блоки данных можно пока сохранить. С такой логикой, раз уж мы скопировали из памяти избыточные данные, пока оставим, вдруг пригодятся.
____Теперь, размер локальной памяти мультипроцессора составляет 64 Кб и её можно сконфигурировать программно, оставить 16 Кб разделяемой и 48 Кб нового L1-кэша. Это полезно для старых CUDA-программ, которые не знают о том, что объём разделяемой памяти, доступной блоку нитей, увеличился. Зато они могут выиграть от большего размера кэша. Или сконфигурировать локальную память, в пропорции 48 Кб разделяемой, 16 Кб кэша. То есть, дать возможность программе самой решить, что загружать в память мультипроцессора. Но это тоже будет способствовать росту производительности старых CUDA-программ, так как большее количество блоков и нитей сможет одновременно выполняться на мультипроцессоре. Допустим, если раньше один блок из 256 нитей требовал 16 Кб разделяемой памяти и на мультипроцессоре мог выполняться только один блок, то сейчас — 3, так как им всем хватит памяти.
____Также, L1-кэш очень поможет для быстрого свопа, то есть, временного хранения регистров. Сейчас, при программировании CUDA-приложения, желательно использовать как можно меньше регистров мультипроцессора, чтобы на одном мультипроцессоре можно было запустить больше нитей. И, крайне нежелательно, временно сбрасывать содержимое регистров в медленную глобальную память. На это иногда жалуются CUDA-программисты, что им не хватает регистров. А если хватает, то запускается меньше нитей, которые меньше скрывают различные задержки. Приходится думать, как программу реализовать с меньшим количеством временных регистров. Интересная оптимизационная задача конечно. Немного необычно: найти такой нетребовательный алгоритм, иногда бывает похоже на задачу из олимпиады по информатике.
L2–кэш.
____Первая функция общего кэша второго уровня — это радикально ускорить и упростить синхронизацию всех исполняющихся нитей. Нити, выполняющейся на одном мультипроцессоре, не могут видеть содержимое L1–кэшей других мультипроцессоров, но когда данные сбрасываются в L2–кэш, например, принудительными синхронизирующими инструкциями, они сразу становятся видимыми для всех. Раньше, для синхронизации между блоками использовалась сверхмедленная, глобальная память. Это сильно упрощает написание сложных CUDA-программ.
____И, конечно, L2 выступает неким общим пулом загружаемых из глобальной памяти данных. GT200 имеет 256 Кб кэша второго уровня для текстурной памяти на все мультипроцессоры, сейчас размер кэша утроился до 768 Кб. И он стал полноценным, а не только для чтения данных.
____Удобно, конечно, для контроллеров памяти, оперирующих широкими кусками данных, наполнять строчки L1- ; L2-кэшей. Именно в ширине интерфейса глобальной памяти кроется необходимость иметь достаточно большой промежуточный пул и несколько отойти от концепции тратить всю площадь кристалла на исполнительные устройства. Представьте, вы заказываете из магазина товар, но в вашем распоряжении самосвал, он привозит не только товар, но и всё, что рядом лежит. Раньше оно выбрасывалось, а теперь сохраняется в кэше. И конечно, некоторые задачи с объёмом данных, сравнимым с размером кэша, получат очень сильный прирост. Но никакой кэш, тем более, меньше мегабайта размером, не решит проблему доступности данных в случае, близкого к случайному, доступа десятков тысяч одновременно исполняющихся на мультипроцессоре нитей. Для этой цели служит большое количество активных нитей на мультипроцессоре. Кстати, максимальное количество одновременно исполняющихся нитей на мультипроцессоре также возросло.
Поддержка C++.
____Новая версия архитектуры CUDA включает полную поддержку C++, виртуальных функций, указателей на функции и конструкций try–catch. Это расширяет область применения решений на основе архитектуры Fermi и сильно облегчает портирование многих существующих приложений на GPU. Но главное, что многие программисты просто любят программировать на С++, даже если он не очень нужен для решения конкретной задачи. Очень характерно, что часто, обсуждение архитектуры «Ферми» моментально выливается в спор С vs С++. Чтож, скоро сторонники и противники разных подходов к программированию получат ещё одно поле битвы. На чем лучше программировать Fermi? С или С++?
____Но на языках Си свет клином не сошёлся и, благодаря поддержке указателей на функции, стала возможной поддержка большого количества самых разнообразных языков программирования. Причём, не ориентированных на высокую скорость исполнения написанных на них программ.
____Изначально, CUDA предназначалась для высокопроизводительных, во многом оптимизированных приложений, но многие программы выгоднее писать без оглядки на железо, а потом смотреть, как процессоры «страдают», выполняя тяжёлый код и выбирать лучшее для своей задачи. Параллельное программирование проникает в массы и, с полной поддержкой указателей, появилась возможность просто запускать на GPU широкий класс параллельных программ. Fermi и в этом случае может оказаться конкурентоспособным, т. к. такие программы и на классическом CPU будут отчаянно медленно исполняться. И на каждое обращение к памяти у них будет море инструкций обращения к собственным регистрам и так далее.
____Да, для универсализации потребовалось объединить в одном адресном пространстве всю, доступную отдельной нити, память. Собственную память мультипроцессора и видимую глобальную память. Это также важно для заявленной поддержки операторов new и delete, то есть, выделения памяти прямо из CUDA-программы, исполняющейся на CUDA-устройстве. О чём раньше и подумать было нельзя. Очень интересно будет посмотреть, как в реальности будет работать собственный менеджер памяти.
Программные улучшения.
____Компания NVIDIA заявляет об увеличении скорости переключения задач, поскольку на GPU может выполняться несколько CUDA-приложений. Но более важно то, что теперь одновременно может выполняться несколько CUDA-функций одного приложения. Потому, что одна может не загрузить всё устройство. И это делает возможным плотнее загрузить поддерживающий CUDA GPU при запуске нескольких задач подряд. Так как программа, приближаясь к своему завершению, может работать лишь на нескольких мультипроцессорах, в то время как остальные уже освободились.
____Исполнение нескольких функций может помочь скрыть длительное время передачи данных по шине PCI-Express. Чтобы GPU не останавливался в ожидании передачи данных. Может быть, даже одну задачу выгодно будет делить на несколько меньших, чтобы первые блоки уже начинали считать, пока подгружаются остальные данные.
Заключение.
____Последний пункт особенно чётко демонстрирует «суперкомпьютерный» характер новой архитектуры. Можно смело сказать, что мы получаем настоящий суперкомпьютер на столе. Страшно подумать, что их ещё можно установить несколько в одной системе и объединить вместе несколько таких компьютеров. Получается целый вычислительный фрактал. Перечислим его: нить — полуварп (16) — варп (2*16) — блок нитей (2*16*8 ) — мультипроцессор (2*16*8*4) — GPU (2*16*8*4*30) — multiGPU (2*16*8*4*30*4) — узел из 8 компьютеров (2*16*8*4*30*4*8 )= ~ пол миллиона нитей и десять тысяч операций за одну миллиардную секунды. И дешевле обычного сервера.
____«Революционность» новой архитектуры заключается в том, что улучшения произошли как количественные, так и качественные. Теоретических гигафлопов стало намного больше, особенно в вычислениях с двойной точностью. Одновременно с этим, их стало гораздо легче получить, как с точки зрения улучшения аппаратного обеспечения, так и со стороны поддержки средств разработки.
Ссылки.
- NVIDIA's GT200: Inside a Parallel Processor
Обзор микросхемы GT200, с точки зрения внутренней микроархитектуры. - Inside Fermi: Nvidia’s HPC Push
Превью-обсуждение микроархитектуры «Ферми», возможных вариантов внутренней реализации. Правда, обзоры написаны чисто с точки зрения аппаратного обеспечения, автор обзоров предпочитает считать нити «векторными линиями». Хотя, с точки зрения программирования, они вполне самостоятельны. - NVIDIA Fermi Compute Architecture Whitepaper
Описание новой архитектуры «Ферми» от разработчика. - CUDA Zone
Красочный список программ, использующих CUDA, а также различных работ, посвященных CUDA. Есть возможность выбрать программу из интересуемой области и посмотреть, какую производительность можно ожидать, а также что, в принципе, можно реализовать с помощью CUDA. Но не все представленные там программы полностью используют возможности CUDA, что-то можно написать более оптимально. - ComputeWorks
CUDA SDK с примерами использования CUDA в самых различных областях от самой NVIDIA. Они (примеры) представлены как в исходных кодах, так и в виде готовых исполняемых файлов. Также, можно выбрать пример из нужной области и оценить прирост производительности. Есть примеры с графикой и с научными или экономическими вычислениями.
Для ознакомления, лучше всего выбирать примеры из знакомой области, чтобы можно было понять, что можно получить, в сравнении с известными CPU-реализациями. Так как прирост от использования CUDA, сильно зависит от конкретного алгоритма. - Источник
Конец.
.
Viktor2312- RIP
- Сообщения : 15492
Дата регистрации : 2012-08-10
Возраст : 45
Откуда : Пятигорск
Похожие темы
» Микропроцессоры. Статьи
» Статьи, заметки, очерки...
» Статьи, описания, информация
» Статьи, заметки, очерки...
» Книги, статьи (proklondike.net).
» Статьи, заметки, очерки...
» Статьи, описания, информация
» Статьи, заметки, очерки...
» Книги, статьи (proklondike.net).
Страница 1 из 1
Права доступа к этому форуму:
Вы не можете отвечать на сообщения