Home Knowledge Base Parallel Reduction Operations

Parallel Reduction Operations are the fundamental collective computation pattern that combines N values into a single result (sum, max, min, product) using a tree-structured algorithm that achieves O(log N) steps with N/2 processors — serving as the building block for virtually all aggregate computations in parallel programming, from computing loss function sums across GPU threads to global AllReduce operations across distributed training clusters.

Reduction Tree Structure

Step 0:  [a₀] [a₁] [a₂] [a₃] [a₄] [a₅] [a₆] [a₇]   (8 values)
           \ /       \ /       \ /       \ /
Step 1:  [a₀+a₁]  [a₂+a₃]  [a₄+a₅]  [a₆+a₇]         (4 partial sums)
              \    /              \    /
Step 2:  [a₀..a₃]           [a₄..a₇]                   (2 partial sums)
                  \        /
Step 3:        [a₀..a₇]                                 (final sum)

GPU Block-Level Reduction

__global__ void blockReduce(float *input, float *output, int n) {
    __shared__ float sdata[256];  // Shared memory for block
    int tid = threadIdx.x;
    int i = blockIdx.x * blockDim.x + threadIdx.x;
    
    // Load to shared memory
    sdata[tid] = (i < n) ? input[i] : 0.0f;
    __syncthreads();
    
    // Tree reduction in shared memory
    for (int s = blockDim.x / 2; s > 32; s >>= 1) {
        if (tid < s) sdata[tid] += sdata[tid + s];
        __syncthreads();
    }
    
    // Warp-level reduction (no sync needed within warp)
    if (tid < 32) {
        float val = sdata[tid];
        val += __shfl_down_sync(0xFFFFFFFF, val, 16);
        val += __shfl_down_sync(0xFFFFFFFF, val, 8);
        val += __shfl_down_sync(0xFFFFFFFF, val, 4);
        val += __shfl_down_sync(0xFFFFFFFF, val, 2);
        val += __shfl_down_sync(0xFFFFFFFF, val, 1);
        if (tid == 0) output[blockIdx.x] = val;
    }
}

Optimization Levels

OptimizationTechniqueImprovement
Sequential → parallelTree reductionO(N) → O(log N) time
Avoid divergent warpsStride-based indexing2× on early steps
Avoid bank conflictsSequential addressing10-20%
Warp-level (no sync)Shuffle instructions instead of shared mem2× for last 5 steps
Grid-level reductionCooperative groups or atomicSingle kernel launch
Library callcub::DeviceReduceAuto-optimized

Multi-Level Reduction (Large Data)

Level 1: Each thread block reduces 256 elements → block partial sum
Level 2: Second kernel reduces block partial sums → final result

Alternative: Single kernel with cooperative groups
  → All blocks synchronize via grid-level barrier
  → Avoids second kernel launch overhead

CUB Library (NVIDIA)

#include <cub/cub.cuh>

// Block-level reduction
typedef cub::BlockReduce<float, 256> BlockReduce;
__shared__ typename BlockReduce::TempStorage temp;
float block_sum = BlockReduce(temp).Sum(thread_val);

// Device-level reduction
cub::DeviceReduce::Sum(d_temp, temp_bytes, d_input, d_output, n);

Reduction Beyond Sum

OperationAssociativeCommutativeGPU Support
SumYesYesNative
Max/MinYesYesNative
ProductYesYesCustom
ArgmaxYesNo (need index)Custom
HistogramNo (but segmentable)Specialized

Parallel reduction is the most fundamental collective operation in all of parallel computing — every dot product, every loss function computation, every gradient aggregation, and every global synchronization ultimately relies on efficient reduction, making it the single most important algorithmic pattern to master for anyone writing high-performance GPU or distributed computing code.

hardware reductiongpu reduction operationparallel reduction treewarp reduceblock reduction

Explore 500+ Semiconductor & AI Topics

From EUV lithography to CUDA optimization — search the full knowledge base or chat with our AI assistant.