Ответ 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)