원클릭으로
triton-cuda-memory
CUDA GPU 内存访问优化策略,包括共享内存利用、合并访存、Bank Conflict 避免和数据布局优化技巧。适用于内存带宽受限、需要优化全局内存访问效率、或处理大规模数据的 CUDA 内核性能优化场景
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
CUDA GPU 内存访问优化策略,包括共享内存利用、合并访存、Bank Conflict 避免和数据布局优化技巧。适用于内存带宽受限、需要优化全局内存访问效率、或处理大规模数据的 CUDA 内核性能优化场景
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
矩阵乘法矩阵乘法 A[M, K] @ B[K, N] = C[M, N]中,大K维度矩阵乘法(K>>M,N)优化:针对M/N较小但K极大(如M=N=256,K=131072)的场景,Split-K切分K维度并行化、Workspace+Reduce替代全局同步,实现显著性能提升
Triton Ascend hard API restrictions and forbidden syntax. MUST-follow rules that apply to every kernel: forbidden control flow (return/break/continue/lambda/while), tensor slice/index restrictions, scalar conversion rules, BLOCK_SIZE upper bound. Violating any of these produces a compile or runtime error on Ascend.
Triton Ascend 性能优化通用策略: BLOCK_SIZE 选择 (1024-2048 for elementwise, must be <65536), grid configuration (use VEC_CORE_NUM / CUBE_CORE_NUM, 2D/3D grid for matmul / conv / reduce, 1D grid + inner loop for elementwise / pointwise), 256B alignment for memory transfers, autotune block-size patterns, fp16 / fp32 precision conversion. Bind via keywords like matmul, elementwise, reduce, block_size, grid, autotune, alignment, fp16, fp32, tile, interleaved-loop, cube-core, vec-core.
通过 adaptive_search 或 evolve 搜索式 workflow 生成优化算子。 后台 silent mode 执行,轮询监控进度。
适用于归约(reduce)类算子和含归约子步骤的复合算子(如归一化)的优化指南。典型算子包括:sum, mean, max, min, prod, argmax, argmin, cumsum, cumprod, softmax, logsoftmax, layernorm, rmsnorm, groupnorm, instancenorm, batchnorm, l1norm, l2norm, frobeniusnorm, var, std, average_pooling, sum_pooling 等。特别重要:当归约维度不是最后一维(如 dim=1 归约 shape=[B,F,D1,D2]),需要正确处理多维索引和两阶段归约。包含 PyTorch normalized_shape 多轴归一化语义说明。不适用于纯逐元素运算或矩阵乘法。如果算子是损失函数(先逐元素计算再全局归约),应选择 elementwise-reduce-fused 指南。
CPU C++ 算子核心概念、标准结构模式、KernelBench 代码规范和内嵌扩展方法
| name | triton-cuda-memory |
| description | CUDA GPU 内存访问优化策略,包括共享内存利用、合并访存、Bank Conflict 避免和数据布局优化技巧。适用于内存带宽受限、需要优化全局内存访问效率、或处理大规模数据的 CUDA 内核性能优化场景 |
| category | implementation |
| version | 1.0.0 |
| metadata | {"backend":"cuda","dsl":"triton_cuda"} |
内存访问是 GPU 性能的关键瓶颈。本文档提供 Triton CUDA 的内存访问优化策略。
| 内存类型 | 带宽 (A100) | 延迟 | 容量 |
|---|---|---|---|
| 寄存器 | ~19 TB/s | 1 cycle | 256 KB/SM |
| 共享内存 | ~19 TB/s | ~20 cycles | 164 KB/SM |
| L2 缓存 | ~5 TB/s | ~100 cycles | 40 MB |
| 全局内存 (HBM) | ~2 TB/s | ~400 cycles | 40/80 GB |
当同一 warp 中的 32 个线程访问连续的内存地址时,GPU 可以将这些请求合并为一次或少量内存事务,大幅提高带宽利用率。
# 正确:合并访问(连续地址)
@triton.jit
def coalesced_kernel(input_ptr, output_ptr, n, BLOCK_SIZE: tl.constexpr):
pid = tl.program_id(0)
offsets = pid * BLOCK_SIZE + tl.arange(0, BLOCK_SIZE) # 连续偏移
mask = offsets < n
data = tl.load(input_ptr + offsets, mask=mask)
tl.store(output_ptr + offsets, data, mask=mask)
# 错误:非合并访问(跳跃地址)
@triton.jit
def strided_kernel(input_ptr, output_ptr, n, stride, BLOCK_SIZE: tl.constexpr):
pid = tl.program_id(0)
offsets = pid * BLOCK_SIZE + tl.arange(0, BLOCK_SIZE)
# 每个线程跳跃 stride 个元素,导致非合并访问
strided_offsets = offsets * stride
mask = strided_offsets < n
data = tl.load(input_ptr + strided_offsets, mask=mask)
tl.make_block_ptr对于 2D 数据(如矩阵),优先使用 tl.make_block_ptr 配合 boundary_check,可自动优化内存合并。
@triton.jit
def matmul_kernel(
A_ptr, B_ptr, C_ptr,
M, N, K,
stride_am, stride_ak,
stride_bk, stride_bn,
stride_cm, stride_cn,
BLOCK_M: tl.constexpr,
BLOCK_N: tl.constexpr,
BLOCK_K: tl.constexpr,
):
pid_m = tl.program_id(0)
pid_n = tl.program_id(1)
# 创建 2D Block Pointer
A_block_ptr = tl.make_block_ptr(
base=A_ptr,
shape=(M, K),
strides=(stride_am, stride_ak),
offsets=(pid_m * BLOCK_M, 0),
block_shape=(BLOCK_M, BLOCK_K),
order=(1, 0), # Row-major
)
# 使用 boundary_check 自动处理边界
a = tl.load(A_block_ptr, boundary_check=(0, 1))
class ModelNew(torch.nn.Module):
def __init__(self):
super().__init__()
def forward(self, input_tensor):
# 非连续张量转为连续(一次性开销)
if not input_tensor.is_contiguous():
input_tensor = input_tensor.contiguous()
output_tensor = torch.empty_like(input_tensor)
n_elements = input_tensor.numel()
grid = (triton.cdiv(n_elements, BLOCK_SIZE),)
elementwise_kernel[grid](
input_tensor, output_tensor,
n_elements,
BLOCK_SIZE=1024
)
return output_tensor
| 方案 | 优势 | 劣势 |
|---|---|---|
.contiguous() + 一维访问 | 合并访问,缓存友好 | 一次性内存拷贝开销 |
| stride 访问 | 无需拷贝 | 非合并访问,累积开销大 |
建议:非连续张量先调用 .contiguous() 转换,再用一维访问,整体性能更优。
对于 MatMul 等 2D 算子,通过分组遍历提高 L2 缓存命中率:
# 标准遍历:L2 缓存利用率低
pid_m = pid // num_pid_n
pid_n = pid % num_pid_n
# Grouped Ordering:L2 缓存利用率高
GROUP_SIZE_M = 8
num_pid_in_group = GROUP_SIZE_M * num_pid_n
group_id = pid // num_pid_in_group
first_pid_m = group_id * GROUP_SIZE_M
group_size_m = min(num_pid_m - first_pid_m, GROUP_SIZE_M)
pid_m = first_pid_m + ((pid % num_pid_in_group) % group_size_m)
pid_n = (pid % num_pid_in_group) // group_size_m
task_m, task_n = tl.swizzle2d(pid_m, pid_n, num_pid_m, num_pid_n, GROUP_SIZE)
通过 num_stages 控制预取级数,隐藏内存延迟:
@triton.autotune(
configs=[
triton.Config({...}, num_stages=2, num_warps=4),
triton.Config({...}, num_stages=3, num_warps=4),
triton.Config({...}, num_stages=4, num_warps=8),
],
key=[...],
restore_value=['output_ptr'], # 必须:列出所有输出指针参数名
)
input.contiguous()ptr + offsetstl.make_block_ptrboundary_checktensor.is_contiguous()