You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

CuPy代码优化:如何加速嵌套for循环

优化方案

核心优化思路

原代码的三层Python循环会带来显著的CPU-GPU调度开销,多次创建中间张量也会浪费内存带宽。我们通过向量化xb维度的计算减少循环层数,同时合并部分einsum步骤降低中间内存占用,所有中间张量规模均不超过dim^4,符合约束要求。

优化后的代码

import numpy as np
import cupy as cp
from time import perf_counter

dim = 60
T_final = cp.random.rand(dim,dim,dim,dim)
T_start = cp.random.rand(dim,dim,dim,dim)
U = cp.random.rand(dim,dim,dim)

# 预先转置T_start,方便批量处理xb维度
T_start_xb_first = T_start.transpose(1, 0, 2, 3)  # shape: (xb, xf, k, s)

cp.cuda.Stream.null.synchronize()
start = perf_counter()

for xf in range(dim):
    for yu in range(dim):
        # 合并B和C的计算,直接得到所有xb对应的C张量,避免创建中间B
        C_all = cp.einsum("ij, kim, xkjs->xms", U[:,:,yu], T_start[xf,:,:,:], T_start_xb_first[:, xf, :, :])
        # 批量计算并赋值T_final的对应切片
        T_final[xf,:,yu,:] = cp.einsum("msc, xms->xc", U, C_all)

cp.cuda.Stream.null.synchronize()
print(perf_counter()-start)

额外优化建议

  1. 替换部分einsum为tensordot/matmul:对于简单张量收缩,cp.tensordot或cp.matmul的底层实现通常比einsum更高效。例如C_all的计算可拆分为两步tensordot:
    B = cp.tensordot(T_start[xf,:,:,:], U[:,:,yu], axes=1)  # 等价于原einsum生成的B
    C_all = cp.tensordot(B, T_start_xb_first[:, xf, :, :], axes=([0,2], [1,2]))
    
  2. 启用自动混合精度:若计算精度允许,使用cp.amp.autocast()上下文管理器,可进一步提升GPU计算效率。
  3. 自定义CUDA核函数:若性能仍未达标,可使用cp.jit.rawkernel编写自定义CUDA核,完全控制内存访问模式与计算流程,最大化GPU利用率。

内容的提问来源于stack exchange,提问作者Indiano

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 20:37:01