ワンクリックで
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()