Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
直接コマンドでは確認用 Prompt が省略されます。実行前にソースを確認してください。
npx skills add https://github.com/mindspore-ai/akg --skill cuda-basicsコマンドは1行のまま表示されます。コピー前に横へスクロールして全体を確認してください。
ローカルで確認しますか?SkillsMP が現在取得できるファイルをダウンロードできます。
矩阵乘法矩阵乘法 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.
SOC 職業分類に基づく
SKILL.md を表示中
| name | cuda-basics |
| description | CUDA编程基础知识,包括内存模型、线程层次和常用优化技巧 |
| category | dsl |
| version | 1.0.0 |
| license | MIT |
CUDA (Compute Unified Device Architecture) 是NVIDIA推出的并行计算平台和编程模型。
Grid (网格)
└─ Block (块)
└─ Thread (线程)
// 1D
dim3 block(256);
dim3 grid((N + 255) / 256);
// 2D
dim3 block(16, 16);
dim3 grid((M + 15) / 16, (N + 15) / 16);
// 3D
dim3 block(8, 8, 8);
dim3 grid((M + 7) / 8, (N + 7) / 8, (K + 7) / 8);
// 1D索引
int idx = blockIdx.x * blockDim.x + threadIdx.x;
// 2D索引
int row = blockIdx.y * blockDim.y + threadIdx.y;
int col = blockIdx.x * blockDim.x + threadIdx.x;
// 全局1D索引(从2D)
int idx = row * width + col;
| 内存类型 | 位置 | 访问速度 | 大小 | 作用域 | 生命周期 |
|---|---|---|---|---|---|
| Register | 片上 | 最快 | ~64KB/SM | Thread | Thread |
| Shared Memory | 片上 | 快 | 48KB-164KB | Block | Block |
| L1 Cache | 片上 | 快 | 128KB | - | - |
| L2 Cache | 片上 | 中 | MB级 | - | - |
| Global Memory | DRAM | 慢 | GB级 | Grid | Application |
| Constant Memory | DRAM | 中(有cache) | 64KB | Grid | Application |
| Texture Memory | DRAM | 中(有cache) | - | Grid | Application |
// Register (自动)
int local_var;
// Shared Memory
__shared__ float shared_data[256];
// Global Memory
__global__ void kernel(float* global_data) { }
// Constant Memory
__constant__ float const_data[1024];
// ✅ 好:连续访问
__global__ void coalesced_read(float* data) {
int idx = blockIdx.x * blockDim.x + threadIdx.x;
float val = data[idx]; // 线程连续访问
}
// ❌ 差:跨步访问
__global__ void strided_read(float* data, int stride) {
int idx = (blockIdx.x * blockDim.x + threadIdx.x) * stride;
float val = data[idx]; // 线程跨步访问
}
__global__ void use_shared_memory(float* input, float* output) {
__shared__ float tile[TILE_SIZE];
int tid = threadIdx.x;
int gid = blockIdx.x * blockDim.x + threadIdx.x;
// 从全局内存加载到共享内存
tile[tid] = input[gid];
__syncthreads(); // 同步
// 从共享内存读取(快速)
float val = tile[tid];
// 处理...
output[gid] = val;
}
Shared memory分为32个bank,同时访问同一bank的不同地址会导致冲突。
// ❌ 有Bank Conflict
__shared__ float data[32][32];
float val = data[threadIdx.x][threadIdx.y]; // 列访问导致冲突
// ✅ 无Bank Conflict(通过padding)
__shared__ float data[32][33]; // 多一列padding
float val = data[threadIdx.x][threadIdx.y];
__syncthreads(); // 等待block内所有线程到达此点
__syncwarp(); // 等待warp内所有线程
atomicAdd(&counter, 1); // 原子加
atomicMax(&max_val, val); // 原子最大值
atomicCAS(&lock, 0, 1); // Compare-and-Swap
// 手动展开
#pragma unroll
for (int i = 0; i < 4; ++i) {
sum += data[i];
}
// 完全展开
sum = data[0] + data[1] + data[2] + data[3];
在warp内线程间交换数据,无需共享内存:
// Warp reduce
__device__ float warp_reduce_sum(float val) {
for (int offset = 16; offset > 0; offset /= 2) {
val += __shfl_down_sync(0xffffffff, val, offset);
}
return val;
}
// 使用float4一次加载4个float
float4 val = reinterpret_cast<float4*>(data)[idx];
// 经验法则
// - Warp大小的倍数(32)
// - 考虑register和shared memory限制
// - 常用: 128, 256, 512
dim3 block(256); // 常见选择
// 向上取整
int grid_size = (N + block_size - 1) / block_size;
// 使用occupancy calculator
int minGridSize, blockSize;
cudaOccupancyMaxPotentialBlockSize(
&minGridSize, &blockSize,
my_kernel, 0, 0
);
#define CUDA_CHECK(call) { \
cudaError_t err = call; \
if (err != cudaSuccess) { \
printf("CUDA Error: %s\n", cudaGetErrorString(err)); \
exit(1); \
} \
}
CUDA_CHECK(cudaMalloc(&d_data, size));
__global__ void debug_kernel() {
if (threadIdx.x == 0 && blockIdx.x == 0) {
printf("Debug: value = %d\n", value);
}
}
cuda-gdb ./program
(cuda-gdb) break my_kernel
(cuda-gdb) run
(cuda-gdb) cuda thread
#include <cuda_runtime.h>
#include <stdio.h>
__global__ void vector_add(const float* A, const float* B, float* C, int N) {
int idx = blockIdx.x * blockDim.x + threadIdx.x;
if (idx < N) {
C[idx] = A[idx] + B[idx];
}
}
int main() {
int N = 1000000;
size_t size = N * sizeof(float);
// 主机内存
float *h_A = (float*)malloc(size);
float *h_B = (float*)malloc(size);
float *h_C = (float*)malloc(size);
// 初始化数据
for (int i = 0; i < N; i++) {
h_A[i] = i;
h_B[i] = i * 2;
}
// 设备内存
float *d_A, *d_B, *d_C;
cudaMalloc(&d_A, size);
cudaMalloc(&d_B, size);
cudaMalloc(&d_C, size);
// 拷贝到设备
cudaMemcpy(d_A, h_A, size, cudaMemcpyHostToDevice);
cudaMemcpy(d_B, h_B, size, cudaMemcpyHostToDevice);
// 启动kernel
int blockSize = 256;
int gridSize = (N + blockSize - 1) / blockSize;
vector_add<<<gridSize, blockSize>>>(d_A, d_B, d_C, N);
// 拷贝回主机
cudaMemcpy(h_C, d_C, size, cudaMemcpyDeviceToHost);
// 验证结果
for (int i = 0; i < 10; i++) {
printf("C[%d] = %f\n", i, h_C[i]);
}
// 清理
cudaFree(d_A);
cudaFree(d_B);
cudaFree(d_C);
free(h_A);
free(h_B);
free(h_C);
return 0;
}
# 计算理论FLOPS
peak_flops = num_sms * clock_mhz * ops_per_clock * 1e6
# 计算理论带宽
peak_bandwidth_gb_s = memory_bus_width / 8 * memory_clock_mhz * 2 / 1000
Performance = min(
Peak_FLOPS,
Peak_Bandwidth * Arithmetic_Intensity
)
__syncthreads()