Ao implementar algoritmos de alta performance em GPUs NVIDIA, a biblioteca CUB é essencial. No entanto, sua API tradicional de 'duas fases (two-phase)', que separa a estimativa de memória temporária da alocação, muitas vezes resulta em código confuso. Este post explora a nova API de chamada única (single-call) disponível a partir do CUDA 13.1 e como ela melhora a experiência do desenvolvedor. Para o anúncio original, confira o material de referência no blog de desenvolvedores da NVIDIA.

O Problema da API de Duas Fases
O padrão antigo exigia duas chamadas: primeiro para determinar o tamanho do armazenamento temporário, depois para alocar e executar.
// PRIMEIRA CHAMADA: determina o tamanho do armazenamento temporário
cub::DeviceScan::ExclusiveSum(nullptr, temp_storage_bytes, d_input, d_output, num_items);
// Aloca o armazenamento temporário necessário
cudaMalloc(&d_temp_storage, temp_storage_bytes);
// SEGUNDA CHAMADA: executa o scan de fato
cub::DeviceScan::ExclusiveSum(d_temp_storage, temp_storage_bytes, d_input, d_output, num_items);
Embora oferecesse flexibilidade, essa abordagem gerava código repetitivo e ambiguidade sobre quais parâmetros poderiam mudar entre as chamadas.

Vantagens da Nova API de Chamada Única
A nova API condensa tudo em uma linha. Ela gerencia a alocação internamente, sem overhead de performance. Olha só essa comparação 👇
| Funcionalidade | API Legada de Duas Fases | Nova API de Chamada Única |
|---|---|---|
| Número de Chamadas | 2 (Consulta + Execução) | 1 🎯 |
| Alocação Explícita | Obrigatória (cudaMalloc) | Não Obrigatória (Interna) |
| Legibilidade do Código | Baixa (Muito Boilerplate) | Alta ✨ |
| Overhead de Performance | Nenhum | Nenhum ⚡ |
| Controle de Execução | Limitado | Flexível via argumento env |
A nova API mantém a flexibilidade através do argumento env, permitindo passar recursos de memória ou um stream CUDA.

Dicas Práticas e Conclusão
Algoritmos-chave como cub::DeviceReduce::Sum e cub::DeviceScan::ExclusiveSum agora suportam a nova interface. Usando o argumento env, você pode controlar finamente o ambiente de execução combinando pools de memória personalizados ou streams específicos. Vamos lá! Esse novo padrão permite escrever código mais limpo sem sacrificar performance. Comece a usar hoje mesmo com CUDA 13.1 ou superior. 🚀