Pytorch 内存布局优化:Contiguous Memory

1、什么是"连续内存"(Contiguous Memory)

🎯 "连续内存"(Contiguous Memory)

  • 连续内存:张量的元素在内存中按顺序排列,没有间隔

  • 非连续内存:张量的元素在内存中可能是跳跃存储的

    import torch

    创建一个连续张量

    x = torch.tensor([[1, 2, 3],
    [4, 5, 6]])
    print(x.is_contiguous()) # True - 内存连续

    转置操作会产生非连续张量

    x_t = x.T # 转置
    print(x_t.is_contiguous()) # False - 内存不连续

    print("原始张量:", x.stride()) # (3, 1) - 到下一行步长为3,下一列步长为1
    print("转置张量:", x_t.stride()) # (1, 3) - 到下一行步长为1,下一列步长为3

2、为什么需要连续内存

🎯 性能差异

  • 连续内存:CPU/GPU可以顺序读取,缓存友好,计算速度快

  • 非连续内存:需要跳跃访问内存,缓存不友好,计算速度慢

    import time

    创建大张量测试性能差异

    x = torch.randn(1000, 1000)

    连续版本

    x_contiguous = x.contiguous()
    start = time.time()
    result1 = x_contiguous @ x_contiguous.T
    time_contiguous = time.time() - start

    非连续版本(通过转置创建)

    x_non_contiguous = x.T.T # 转置两次,制造非连续
    start = time.time()
    result2 = x_non_contiguous @ x_non_contiguous.T
    time_non_contiguous = time.time() - start

    print(f"连续内存计算时间: {time_contiguous:.4f}s")
    print(f"非连续内存计算时间: {time_non_contiguous:.4f}s")
    print(f"性能差异: {time_non_contiguous/time_contiguous:.2f}x")

3、什么操作会产生非连续张量

复制代码
x = torch.randn(3, 4)
print("原始张量连续:", x.is_contiguous())  # True

# 以下操作可能产生非连续张量
non_contiguous_ops = [
    x.T,           # 转置
    x[:, ::2],     # 带步长的切片
    x.permute(1, 0),  # 维度重排
    x.transpose(0, 1) # 转置
]

for i, tensor in enumerate(non_contiguous_ops):
    print(f"操作{i+1}连续:", tensor.is_contiguous())  # 都是False

4、内存布局如何优化

🎯 **.contiguous()**的作用

  • 创建原张量的一个副本,保证内存布局连续

  • 如果原张量已经连续,直接返回原张量(无额外开销)

  • 如果原张量不连续,重新分配连续内存并复制数据

    确保张量在连续内存中

    x = torch.randn(3, 4)
    if not x.is_contiguous():
    # 如果不连续,转换为连续内存布局
    x = x.contiguous()

    大多数PyTorch操作会自动处理连续性

    result = x @ x.T # 更高效,通常这样就够了

    只有在性能关键路径且确定有连续性问题时才手动处理

    if some_complex_operation:
    x = x.contiguous() # 谨慎使用

    def efficient_matrix_ops(x):
    """高效矩阵操作的最佳实践"""
    # 如果x经过复杂变换,确保连续
    if x.is_contiguous():
    # 已经连续,直接使用
    result = x @ x.T
    else:
    # 转换为连续(根据性能需求决定)
    x_contig = x.contiguous()
    result = x_contig @ x_contig.T

    复制代码
      return result

5、什么时候需要显式调用 .contiguous()

复制代码
# 情况1:进行过转置等视图操作后
x = torch.randn(1000, 1000)
x_transposed = x.T  # 转置,现在不连续

# 如果后续要进行大量计算,最好转为连续
if not x_transposed.is_contiguous():
    x_transposed = x_transposed.contiguous()

result = x_transposed @ x_transposed

# 情况2:自定义CUDA内核或需要特定内存布局时

总结

  • 内存连续性影响计算性能
  • 某些操作(如转置)会产生非连续张量
  • **.contiguous()**可以优化内存布局
  • 但在现代PyTorch中,通常不需要手动处理

对于大多数应用,直接使用 x @ x.T就足够了,PyTorch会在内部进行必要的处理。只有在极端的性能优化场景下才需要显式关心内存连续性。

AI知识库将陆续推出大模型算法相关技术!

https://www.yuque.com/lhyyh/ai

相关推荐
清酒难寻5 小时前
深度学习进阶(二十四)Swin 的二维 RPE
人工智能·深度学习
步步为营DotNet5 小时前
借助 Microsoft.Extensions.AI 与 ASP.NET Core 10 实现智能 Web 应用故障预测
人工智能·microsoft·asp.net
AI创界者5 小时前
零基础上手!ComfyUI + LTX-2.3 图生视频完整工作流搭建与调优指南(附避坑细节)
大数据·人工智能
怕浪猫5 小时前
AI图片工具到底有哪些?一份按能力维度整理的清单
人工智能
hongmai6668886 小时前
FH8856V310芯片详解:6M高清+0.5TOPS算力,赋能智能安防新方案
人工智能·单片机·嵌入式硬件·物联网·智能家居
一颗小树x6 小时前
NVIDIA Jetson Thor 运行 LLM / VLM:模型全整理与 vLLM 实践
人工智能·llm·jetson·vllm
每日综合6 小时前
蓝白风暴席卷BW2026!雷克沙展台首日燃情纪实
人工智能
To_OC6 小时前
手搓 LangChain 工具调用:原来 Agent 的核心逻辑,就是个 while 循环
人工智能·langchain·llm
有Li6 小时前
基于扩散模型的超声计算机断层成像实现肌肉骨骼组织高保真三维重建文献速递/基于多模态的医学影像分割与理解
大数据·深度学习·文献·医学生
Drgfd6 小时前
机器人从工厂走进生活:通用机器人开启大众商用时代
人工智能