面试题目收集

ThreadsPerBlock和Blocks的数量受哪些条件约束。

  • ThreadsPerBlock 受 SM寄存器数量, 共享内存大小 和 硬件上限(1024 threads/block)
  • Block数量 受 SM数量和资源容量限制(需要保证所有active blocks的资源总和不超过SM容量) 理论占用率怎么计算?
  • Occupancy = (active warp/SM) / (max warps/SM). 它表示SM上活跃的Warp数量与最大支持的Warp数量之比. 高占用率可以更好地隐藏内存访问延迟, 提高计算吞吐量.
  • GPU以Block为粒度分配资源(寄存器, 共享内存, 线程槽位). 而不是以Warp分配.
  • 寄存器, 共享内存, 线程调度 都是以Block为基础调度的
  • 假如SM支持最多2048个线程(64个warp), 如果每个block有256个线程, 那么SM最多能驻留8个block. 但是因为寄存器和共享内存可能达到上限, SM可能只能驻留4个block.
  • 计算每个block的warp数. Warp per Block = upper bound(Thread per Block / 32)
  • 计算SM能驻留的Block数量, 受限于 寄存器, 共享内存和线程数
  • Active Warp = Warps Per Block x Active Block Per SM
  • 之后计算占用率 什么是warp,什么是warp divergence?
  • Warp 是 SM的基本执行单元, 包含32个线程
  • Warp Divergence 是同以warp内的线程执行不同branch时, 会造成不同branch串行执行, 造成性能损失. cuda的内存模型里有多少种memory,它们的位置(片上还是板上),带宽和延迟的相对大小?
  • register, on chip, 1 cycle latency, highest bandwidth, private for single thread
  • shared memory, on chip, 30 cycle latency, high bandwidth, shared by block
  • local memory, off-chip, dram, in global memory(reality), logically private for single thread
  • global memory, off-chip, dram, 400-800 cycle, low bandwidth, shared by all threads
  • texture and constant, medium latency, medium bandwidth, shared by all threads global memory的访存合并是什么?
  • coalescing access, 同一个warp上的连续线程访问连续global memory地址时会被合并为单个事务. gpu的global memory的事务粒度是128字节.
  • 对于shared memory的优化是避免bank conflict, 共享内存有32个bank. 避免冲突可以使用: 使用padding, 改变访问模式(转置), 使用广播机制(32个线程访问同一个bank上的内容)
  • register分配, 对于自动分配的局部变量, 可能会溢出到local memory上. 什么样的变量会被分配在register上?
  • 分配到寄存器的变量: 小型标量(int, float…), 未取地址的临时变量
  • 不会分配到寄存器的变量: 大数组, 取地址变量, 寄存器溢出 什么样的变量会被分配在local memory上?
  • 大数组
  • 动态索引的数组
__global__ void kernel(int index) {
	int arr[10];
	arr[index] = 0; // dynamic indexing
}
  • 指针操作
__global__ void kernel() {
	int x;
	int *ptr = &x;  // 取地址, register没有地址, 因此存放到local memory
}
  • 溢出的变量
__global__ void complex_calc() {
	float a1, a2, a3, a4, ..., a100;
}

Block是怎么被SM调度执行的?

  • kernel启动时, block分配到gpu的全局队列中去
  • SM 从队列中选择一个或多个block加载到自己的资源池中, 数量由 寄存器总量, 共享内存, 线程槽位(SM支持的线程上限)决定 SM内部的执行调度?
  • Block分解为warp
  • 每个sm有多个warp调度器, 每个周期选择就绪的warp发射指令(要求warp所有的操作数准备好, 也就是没有数据依赖或等待内存访问)
  • 当某个warp因内存访问或计算延迟停滞的时候, 调度器立即切换到其他就绪warp
  • 高占用率能更好的隐藏延迟 什么是cuda core?
  • nvidia的并行计算核心, 负责浮点或整数运算. 支持fp16, fp32 和fp64. 什么是tensor core?
  • nvidia用来加速矩阵计算的计算核心, 核心功能包括:
    • 矩阵乘累加操作(MMA, D=AxB + C). 支持混合精度计算, (fp16输入, fp32累加)
    • 每个时钟周期能完成更多矩阵操作
    • 固化电路实现矩阵乘法, 减少指令开销, 提高能效. 什么是bank conflict?
  • bank conflict发生在shared memory被访问时. 当多个线程试图访问同一个bank的不同地址时, 这些访问会被串行化.
  • 同一个时钟周期, 多个线程(无论是否属于同一个warp)访问同一个bank的不同地址时, 会发生bank conflict. 怎么避免bank conflict,你能想到多少方法?
  • 使用padding, 调整数据布局
  • 使用广播机制 描述一下Block reduce的大致实现。
  • 共享内存暂存数据, 循环折半求和
  • thread 内部在register上做reduce
  • warp 使用shuffle指令做reduce操作
  • block使用shared memory 做reduce操作 描述一下double buffer(ping pong buffer)的大概原理和实现。
  • 双缓冲区交替执行计算和数据传输, 隐藏延迟(一个buffer进行绘制, 绘制完成后, 这个buffer被指定为输出buffer, 进行画面输出) 什么是roofline model?
  • roofline model 是一个判断模型所能达到性能上限由什么决定的模型(memory bound or computation bound). 通过计算一个模型的计算强度I和I_max(算力平台的 算力 / 带宽) 做对比, 在I_max左侧的, 其模型性能与计算强度成正比, 是memory bound的. 如果在I_max右侧, 其模型性能与最大算力pi 什么是memory bound,什么是computation bound?
  • Memory Bound:性能随计算强度线性增长,但无法超过内存带宽的限制。 - Compute Bound:计算强度足够高,性能受限于硬件算力上限。 kernel fusion为什么能提升性能?
  • 什么是kernel fusion? kernel fusion就是将多个小kernel合并成一个更大的kernel. 从而减少内核启动开销, 并减少冗余内存访问(因为小kernel需要将结果写到global memory并读取).
  • 减少内核启动开销
  • 提高数据局部性(不需要读和写global memory, 直接使用register和shared memory)
  • 节省显存带宽 还有哪些好处?举几个fusion的例子。gpu上有分支预测吗?
  • 深度学习中的激活函数和卷积融合
conv2d_kernel<<<...>>>(input, weights, conv_output);
relu_kernel<<<...>>>(conv_output, output);

//fusion
fused_conv_relu_kernel<<<...>>>(input, weights, output);


FMA(fused multiple and add)
multiply_kernel<<<...>>>(A, B, C);
add_kernel<<<...>>>(C, D, E);
fused_multiply_add_kernel<<<...>>>(A, B, D, E);
// use fused multiply-add, FMA directly
  • gpu有简单的分支预测 gpu上有指令集并行吗?

常用profile工具和方法。

  • nsight 系列(nsight systems, nsight compute)

  • nsight systems 是系统级分析, 主要功能包括: CPU/GPU时间线, API调用, CUDA内核执行, 显存/带宽等.

  • nsight compute 主要是详细分析寄存器使用, 吞吐量, 内存访问模式等.

  • 重要的指标: GPU Utilization, Bandwidth, Warp 效率, 寄存器/共享内存: spill? kernel耗时.

  • 方法论: 时间线分析, 例如是否有太多Memcpy导致的的GPU空转等等. 定位低效的kernel进行重点优化. float的计算一定比int消耗更多的cycle吗(主要是加法和乘法)?

  • 在相同位宽(如INT32 vs FP32)下,简单运算(add and mul)可能cycle相近,但复杂运算浮点更慢(div)。 常见的float格式。fp32,tf32,fp16,bf16的联系和区别?

  • 浮点数, fp32 在ieee754标准中, 由 (1符号位 + 8指数位 + 23位尾数位组成) 使用的基数是2(二进制). 例如对于 0 10000001 01000… 这个fp32浮点数, 其应为 positive(符号位为0), 10000001 = 127 + 2, 表示指数位为2(加127为了给负指数腾出位置, 这里指数的基数为2), 尾数去掉了第一个隐藏1. 因此其表示的数字是 1.01 x 2^2

  • fp32 单精度浮点数, 7位有效十进制数字 (1, 8, 23)

  • tf32 19位(1符号数, 8指数, 10尾数) 在Ampere架构中(使用tensor core), 用于加速矩阵乘(GEMM). 替代FP32在AI训练中的部分计算, 无需修改代码即可加速. (不是存储格式, 仅用于计算时的中间表示) (1, 8, 10)

  • FP16(半精度浮点) 16位(1符号位 + 5指数位 + 10尾数位) (1, 5, 10). 指数位小, 动态范围小.

  • BF16(Brain float 16) (1, 8, 7). 因为指数位相比fp16更多, 动态范围更大, 适合大梯度计算. ptx和sass是什么,和cuda的关系?

  • ptx(parallel thread execution)类似于汇编代码, sass(shader assembly)类似于机器码.

  • cuda 是nvidia推出的并行计算平台和编程模型, 允许开发者用c/cpp编写gpu加速程序 cuda上的排序和topk算法原理和实现。

  • radix sort, merge sort, bitonic sort

  • top-k: radix sort后取前k个. 或者分块数据, 计算局部top-k. 之后对局部top-k进行reduce.

  • radix sort在gpu上的实现. 首先需要做直方图, 统计当前位为0或1的频率. 然后根据直方图, 得到前缀和, 从而知道要排序元素所放的位置, 进行元素重排. matmul的优化,超级加分题。

  • tiling, 通过将大矩阵分解为合适gpu处理的小块

  • 共享内存, 每个thread在进行矩阵计算之前, 先将小块的数据加载到共享内存中(合作加载). 之后再进行计算

  • 共享内存会有bank冲突问题, 为了解决冲突, 使用padding.

  • 双buffer. 在声明shared memory的时候生成两份. 这样可以实现加载下一个块和计算当前块. flash attention的优化,超级加分题。

  • 分块计算, 将QKV矩阵分成小块, 进行计算. 以此实现加载到SRAM上计算

  • 实现计算和IO重叠, (双buffer). 加载下一块到SRAM时, 同时计算当前块

  • 在线softmax. 分块统计最大值(逐块计算局部最大值, 并通过递推公式更新全局最大值), 增量归一化(根据全局最大值和求和结果动态调整输出) 需要额外维护两个变量, 当前块的最大值m和指数求和l

  • kernel fusion. 注意力计算的所有步骤(矩阵乘, softmax, 掩码, dropout)都融合到单个kernel中, 减少启动多个kernel的开销. 提高数据局部性, 节省显存带宽 page attention是什么?

  • flash attention通过优化注意力计算中的内存访问模式, 减少了gpu显存的读写次数, 从而加速了计算

  • 但是它假设了所有的k, v都能连续存储在显存中, 但在长序列任务中不成立

  • 使用分页机制, 将kv cache分成多个页, 动态加载到显存中. 从而避免了显存溢出(OOM). TMA是什么? 和Page attention的关系?

  • TMA(Tensor Memory Accelerator) 是英伟达在Hopper架构中引入的硬件加速技术. 通过硬件级别的paging和内存管理机制, 显著提高大规模张量计算的性能. 什么是专家并行, 张量并行, 数据并行?

  • 数据并行(Data Parallel)是将训练数据划分位多个batch, 分配到不同设备上, 每个设备有模型的完整副本. 独立计算梯度, 最后通过 同步(集合通信, 如all reduce), 聚合梯度更新模型

  • 张量并行(Tensor Parallel) 将模型的单个tensor操作(如矩阵乘法)拆分到多个设备上进行计算. 例如一个大的权重矩阵按行或列分割, 每个设备计算部分结果, 再通过通信拼接输出. 典型场景例如 transformer层中的MLP或注意力计算.

  • 专家并行(Expert Parallel) 专用于混合专家模型(MoE). 将模型中的不同子网络分配到不同设备上, 每个输入样本仅routing到部分专家计算.

  • 存在不同组合, 例如 数据+专家并行, 数据+张量并行, 3D并行(数据, 张量, 流水线)

什么是HBM(high bandwidth memory), 与traditional dram的区别是什么? 当前gpu架构的基本信息(寄存器数量, 内存大小 等等)?

ieee754浮点数标准

  • 指数非全0且非全1, 规格化数字, 正常计算
  • 指数全0, 尾数非0, 非规格化数, 尾数隐藏位不是1, 而是0, 即0.xxxxx, 表示非常小的数字
  • 指数全1, 尾数全0, 正无穷大/负无穷大(看符号位)
  • 指数全0, 且尾数全0时, 表示浮点数为0