Параллельные вычисления
OpenCL и Vulkan Compute
2022 год: Apple выпускает iPhone 14 с чипом A16 Bionic. Neural Engine в нём способен выполнять 17 триллионов операций в секунду. Ни CUDA, ни OpenCL там нет - только Metal. Android флагманы используют Qualcomm Adreno GPU с OpenCL и Vulkan. Игровые консоли - RDNA2 с кастомными API. Реальный мир GPU разработки - это зоопарк платформ, где CUDA - лишь самый известный зверь, но далеко не единственный.
- **TensorFlow Lite** использует Vulkan Compute для GPU ускорения на Android, обеспечивая до 5x ускорение нейронных сетей на мобильных GPU по сравнению с CPU - единственный вариант для Qualcomm, Mali и других mobile GPU
- **MediaPipe** от Google использует OpenCL и Metal для real-time обработки видео (pose estimation, face tracking) на мобильных устройствах - кросс-платформенный подход позволяет поддерживать iOS и Android единой кодовой базой
- **stable-diffusion.cpp** портировал Stable Diffusion на Metal Compute для Apple Silicon, достигнув сопоставимой с CUDA производительности на M1/M2/M3 без зависимости от NVIDIA
OpenCL: CUDA для всех устройств
CUDA работает только на NVIDIA. Apple, AMD, Intel, Qualcomm - все они поддерживают OpenCL (Open Computing Language): открытый стандарт Khronos Group для гетерогенных вычислений. OpenCL абстрагирует не только GPU, но и CPU, FPGA, DSP за единым API. Концептуально OpenCL и CUDA близки: work-item = CUDA thread, work-group = block, NDRange = grid. Kernel на OpenCL C выглядит почти как CUDA C - разница в синтаксисе, не в архитектурных идеях. Платформенная модель: Platform -> Device -> Context -> CommandQueue -> Kernel.
OpenCL 3.0 (2020) сделал большинство расширений опциональными - это упростило реализацию для вендоров, но усложнило написание переносимого кода: нужно проверять поддержку каждой фичи в runtime. Apple убрала OpenCL в macOS 10.14 (deprecated), предложив Metal. Для мобильного GPU: OpenCL ES или Vulkan Compute.
В чём главное отличие OpenCL от CUDA с точки зрения разработки?
Vulkan Compute Shaders: GPU без graphics pipeline
Vulkan - это низкоуровневый graphics API нового поколения от Khronos. В отличие от OpenGL и DirectX, Vulkan предоставляет compute pipeline наравне с graphics pipeline. Compute shader в Vulkan - это программа на GLSL/HLSL, компилируемая в SPIR-V, выполняемая на GPU независимо от рендеринга. Ключевое преимущество: в одном приложении compute работа и рендеринг могут перекрываться через отдельные queue families (compute queue + graphics queue) без блокировок. Именно через Vulkan compute работает TensorFlow Lite на мобильных устройствах с GPU ускорением.
Vulkan compute shader организован через workgroups (аналог CUDA blocks) с локальными (local invocations) и глобальными идентификаторами. Barrier() синхронизирует invocations внутри workgroup. Shared memory называется shared переменными в GLSL. WebGPU (стандарт для браузеров) основан на Vulkan/Metal/D3D12 и использует тот же compute shader принцип через WGSL язык.
Почему Vulkan позволяет перекрывать compute и graphics работу эффективнее, чем OpenGL?
SPIR-V: байткод для GPU шейдеров
Каждый GPU вендор исторически имел собственный компилятор и ISA (Instruction Set Architecture). Разработчик писал GLSL, драйвер компилировал в proprietary формат - это источник несовместимостей и медленного запуска приложений (shader compilation stutter). SPIR-V (Standard Portable Intermediate Representation V) - это промежуточный байткод, подобный LLVM IR или JVM bytecode для GPU. Исходный код (GLSL, HLSL, OpenCL C) компилируется в SPIR-V заранее. Драйвер получает SPIR-V и компилирует в нативный ISA - значительно быстрее, чем из текста. Vulkan требует SPIR-V; OpenCL 2.1+ принимает SPIR-V опционально.
SPIR-V - бинарный формат с фиксированными 32-битными инструкциями. Его можно дизассемблировать в текстовый формат (spirv-dis), оптимизировать (spirv-opt из Google spirv-tools), валидировать (spirv-val). Инструменты: glslangValidator (GLSL -> SPIR-V), DXC (HLSL -> SPIR-V), SPIRV-Cross (SPIR-V -> GLSL/HLSL/MSL для обратной конвертации).
Какую проблему решает SPIR-V по сравнению с прямой передачей GLSL исходника в драйвер?
Кросс-платформенная GPU разработка
Экосистема GPU compute в 2024 году: CUDA (NVIDIA, максимальная производительность), ROCm/HIP (AMD, ~90% CUDA совместимости, можно портировать CUDA код), Metal Compute (Apple Silicon, обязателен для iOS/macOS), WebGPU (браузеры, растущая поддержка), OpenCL (legacy, широкая поддержка), Vulkan Compute (кросс-платформенный, сложный). Для ML задач уровня фреймворков: PyTorch через CUDA/ROCm/Metal, JAX через XLA (компилирует под любое устройство). Для нативной разработки: выбор зависит от целевой платформы.
SYCL (C++ абстракция над OpenCL/CUDA/Metal) от Intel позволяет писать единый код для всех устройств. oneAPI DPC++ компилирует SYCL для NVIDIA GPU через CUDA backend, AMD через ROCm, Intel через OpenCL. Это наиболее перспективный путь к действительно переносимому GPU коду без жертв производительностью.
OpenCL - это кросс-платформенная замена CUDA, дающая одинаковую производительность на всех GPU
OpenCL обеспечивает переносимость кода, но не переносимость производительности. Один и тот же OpenCL kernel может работать в 5-10 раз медленнее на GPU, под который он не оптимизирован
Размер workgroup, использование локальной памяти, паттерны доступа к памяти - всё это зависит от конкретной GPU архитектуры. Высокопроизводительный OpenCL код требует профилирования и настройки под каждый целевой GPU, как и CUDA код
Что такое WebGPU и чем он принципиально отличается от WebGL?
Ключевые идеи
- **OpenCL** - открытый стандарт для GPU/CPU/FPGA вычислений. Переносимость кода между вендорами, но производительность требует оптимизации под каждую архитектуру отдельно
- **Vulkan Compute** предоставляет compute pipeline рядом с graphics, раздельные очереди для параллельного compute/рендеринга, и требует SPIR-V байткод
- **SPIR-V** - промежуточное представление, устраняющее shader compilation stutter и зависимость от качества GLSL компилятора. Компилируется заранее, не в runtime. WebGPU/WGSL - следующий стандарт для браузеров
Связанные темы
OpenCL и Vulkan Compute - альтернативный путь к тем же архитектурным идеям:
- GPU Computing: CUDA основы — CUDA - концептуальная основа: kernels, threads, blocks, shared memory. OpenCL и Vulkan реализуют те же идеи с другим API и большей переносимостью
- GPU Optimization — Техники оптимизации (memory coalescing, occupancy, warp divergence) применимы к OpenCL и Vulkan Compute так же, как к CUDA - аппаратные принципы одинаковы
Вопросы для размышления
- При разработке ML inference движка для мобильного приложения, поддерживающего iOS и Android, какую GPU API стратегию выбрать и почему?
- WebGPU позволяет запускать ML модели в браузере на GPU пользователя. Какие privacy и security преимущества это даёт по сравнению с серверным inference?
- SPIR-V - это промежуточное представление как LLVM IR. Какие оптимизации можно провести над SPIR-V до передачи в драйвер, и чем они принципиально ограничены?