Объяснение CUDA C и С++

Может ли кто-нибудь дать мне хорошее объяснение природе CUDA C и С++? Насколько я понимаю, CUDA должен быть C с библиотеками NVIDIA GPU. На данный момент CUDA C поддерживает некоторые функции С++, но не другие.

Что такое план NVIDIA? Собираются ли они строить на C и добавлять свои собственные библиотеки (например, Thrust vs. STL), которые параллельны С++? В конечном итоге они будут поддерживать все С++? Неправильно ли использовать заголовки С++ в файле .cu?

Ответ 1

CUDA C - это язык программирования с синтаксисом C. Концептуально он сильно отличается от C.

Проблема, которую он пытается решить, - это кодирование нескольких (похожих) команд для нескольких процессоров.

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

CUDA предоставляет некоторые механизмы для этого и скрывает некоторые сложности.

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

CUDA поддерживает "циклы", которые могут выполняться параллельно. Это его самая важная особенность. Система CUDA будет разделять выполнение "циклов" и запускать тело "loop" одновременно через массив идентичных процессоров, обеспечивая при этом некоторую иллюзию обычного последовательного цикла (в частности, CUDA управляет индексом цикла). Разработчик должен знать о структуре машины GPU, чтобы эффективно писать "циклы", но почти все управление обрабатывается временем выполнения CUDA. Эффект завершается сотнями (или даже тысячами) "циклов" одновременно с одним "циклом".

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

Нет "магии". Программист должен знать, что код будет запущен на устройстве CUDA и будет писать код для него.

CUDA не берет старый код C/С++ и автоматически запускает вычисления в массиве процессоров. CUDA может компилировать и запускать обычные C и большую часть С++ последовательно, но этого очень мало (ничего?), Потому что оно будет работать последовательно и медленнее, чем современный процессор. Это означает, что код в некоторых библиотеках пока не подходит для CUDA. Программа CUDA могла одновременно работать с битовыми векторами с несколькими kByte. CUDA не может автоматически модифицировать существующий последовательный код библиотеки C/С++ во что-то, что бы это сделало.

CUDA предоставляет относительно простой способ написания кода, используя знакомый синтаксис C/С++, добавляет несколько дополнительных понятий и генерирует код, который будет работать через массив процессоров. Он может дать намного больше, чем 10-кратное ускорение против, например. многоядерный x86.

Изменить - Планы: я не работаю для NVIDIA

Для лучшей производительности CUDA хочет получить информацию во время компиляции.

Таким образом, механизмы шаблонов являются наиболее полезными, поскольку он дает разработчику способ сказать вещи во время компиляции, которые может использовать компилятор CUDA. В качестве простого примера, если матрица определена (инстанцируется) во время компиляции как 2D и 4 x 8, тогда компилятор CUDA может работать с этим, чтобы организовать программу через процессоры. Если этот размер является динамическим и изменяется во время работы программы, гораздо сложнее выполнить компилятор или систему времени выполнения.

EDIT: CUDA имеет шаблоны классов и функций. Я прошу прощения, если люди читают это, говоря, что CUDA этого не делает. Я согласен, что я был неясен.

Я считаю, что реализация шаблонов CUDA на GPU не является полной w.r.t. С++.

Пользовательский harrism прокомментировал, что мой ответ вводит в заблуждение. harrism работает для NVIDIA, поэтому я буду ждать совета. Надеюсь, это уже понятно.

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

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

AFAIK (по модулю обратной связи) компилятор CUDA еще не является современным в этих областях.

(IMHO стоит потратить несколько дней для всех, кто заинтересован, с системой CUDA или OpenCL, исследовать их и делать некоторые эксперименты. Я также думаю, что для людей, заинтересованных в этих областях, это стоит усилий экспериментировать с Haskell и посмотреть Data Parallel Haskell)

Ответ 2

CUDA - это платформа (архитектура, модель программирования, виртуальная машина сборки, инструменты компиляции и т.д.), а не только один язык программирования. CUDA C является всего лишь одним из нескольких языковых систем, построенных на этой платформе (CUDA C, С++, CUDA Fortran, PyCUDA, являются другими.)

CUDA С++

В настоящее время CUDA С++ поддерживает подмножество С++, описанное в Приложении D ( "Поддержка языка C/С++" ) Руководство по программированию CUDA C.

Чтобы назвать несколько:

  • Классы
  • __device__ функции-члены (включая конструкторы и деструкторы)
  • Наследование/производные классы
  • виртуальные функции
  • шаблоны классов и функций Операторы
  • и перегрузка
  • классы-функторы

Изменить: Начиная с CUDA 7.0, CUDA С++ включает поддержку большинства языковых функций стандарта С++ 11 в коде __device__ (код, который выполняется на графическом процессоре), включая auto, лямбда-выражения, на основе диапазона для циклов, списков инициализаторов, статических утверждений и т.д.

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

Планы на будущее

(Раскрытие: я работаю для NVIDIA.)

Я не могу быть явным о будущих выпусках и сроках, но я могу проиллюстрировать тенденцию, что почти каждая версия CUDA добавила дополнительные языковые функции, чтобы получить поддержку CUDA С++ для ее текущего (на мой взгляд, очень полезного) состояния. Мы планируем продолжить эту тенденцию в улучшении поддержки С++, но, естественно, мы уделяем приоритетное внимание функциям, которые полезны и эффективны на массивно параллельной вычислительной архитектуре (GPU).

Ответ 3

Не реализовано многими, CUDA - это фактически два новых языка программирования, оба из которых основаны на С++. Один для написания кода, который работает на графических процессорах, и является подмножеством С++. Его функция похожа на HLSL (DirectX) или Cg (OpenGL), но с большим количеством функций и совместимостью с С++. К этому относятся различные проблемы GPGPU/SIMT/связанные с производительностью, которые мне не нужно упоминать. Другой - так называемый "Runtime API", который вряд ли является "API" в традиционном смысле. Runtime API используется для написания кода, который выполняется на центральном процессоре. Это надмножество С++ и упрощает связывание и запуск кода графического процессора. Для этого требуется предварительный компилятор NVCC, который затем вызывает компилятор платформы С++. Напротив, API-интерфейс драйвера (и OpenCL) представляет собой чистую стандартную библиотеку C и гораздо удобнее использовать (предлагая несколько дополнительных функций).

Создание нового языка программирования на стороне хоста было смелым шагом на части NVIDIA. Это упрощает работу с CUDA и делает код более элегантным. Тем не менее, поистине блестящий не рекламировал его как новый язык.

Ответ 4

Иногда вы слышите, что CUDA будет C и С++, но я не думаю, что это по той простой причине, что это невозможно. Чтобы привести из своего руководства по программированию:

Для хост-кода nvcc поддерживает любую часть С++ ISO/IEC 14882: 2003, который поддерживает компилятор хоста С++.

Для кода устройства nvcc поддерживает функции, показанные в разделе D.1 с некоторыми ограничениями, описанными в Разделе D.2; Это не поддерживать информацию о типе времени выполнения (RTTI), обработку исключений и Стандартная библиотека С++.

Как я вижу, он относится только к С++ и поддерживает только C, где это происходит в пересечении C и С++. Поэтому лучше подумайте об этом как С++ с расширениями для части устройства, а не C. Это позволяет избежать множества головных болей, если вы привыкли к C.

Ответ 5

Что такое план NVIDIA?

Я считаю, что общая тенденция заключается в том, что CUDA и OpenCL рассматриваются как методы слишком низкого уровня для многих приложений. Прямо сейчас Nvidia вкладывает значительные средства в OpenACC, который можно грубо описать как OpenMP для графических процессоров. Он следует декларативному подходу и решает проблему распараллеливания графических процессоров на гораздо более высоком уровне. Итак, это мое полностью субъективное впечатление от плана Nvidia.