【DOTS学习笔记】面向数据设计DOD

目录

  • 前言
  • 程序设计方法
  • ODD->DOD
  • Cache的3C与3R
  • 面向数据设计需要思考的问题
    • AOS
    • SOA
  • DOTS面向数据设计原则


前言


本文是Metaverse大衍神君的《DOTS之路》系列课程的学习笔记

程序设计方法


  • Instructional Programming 指令化编程
    • 脱离指令打孔输入后,伴随着机器汇编语言发展起来的
  • Functional Programming 函数化编程
    • 伴随着PASCAL语言出现,以小函数模块化组合的编程方式
    • 限制小、易于调试
    • 主要用在数学和科学计算领域
    • 如今的机器学习、AI领域,函数编程依然焕发着活力
  • Procedural Programming 过程化编程
    • 源于命令式的编程方式
    • 基于过程调用的概念,包含要执行的计算步骤
    • 任何给定的过程都可以在程序执行过程中的任何时刻调用
  • Object-Oriented Programming/Design 面向对象编程/设计(OOP/OOD)
    • 以对象为概念的多范式模型
    • 包含字段形式的数据与过程形式的代码
    • 通常以类为基础,强调数据的封装、类的继承与数据的多态特征
  • Data-Oriented Design(DOD) 面向数据设计
    • 伴随着现代CPU多核并行计算、多级缓存、大缓存的设计而流行起来
    • DOD并不是一种编程范式,DOTS式面向数据编程的一种范式

ODD->DOD


  • 面向对象设计->面向数据设计
    • 面向对象设计
      • 核心在于:抽象、封装、继承
      • 对人类来说更直观、易于理解
      • 对现代CPU来说处理效率并不高效
    • 面向数据设计
      • 侧重于数据
      • 需要考虑需要什么数据以及如何在内存中更好的构造数据
      • 以便CPU处理数据系统时,能更有效的访问数据
  • DOD本质:面向内存/缓存友好的设计
    • CPU缓存层级结构
      • CPU 1 cycle
      • L1 Cache 1~5 cycle
        • L1D 数据缓存
        • L1I 指令缓存
      • L2 Cache 5~20 cycle
        • CPU核内多个指令处理单元所共享
      • L3 Cache 20~40 cycle
        • CPU多个核所共享
        • 负责与内存以及显卡中的显存交换数据
      • Main Memory 40~100 cycle

  • CPU在执行指令程序时,通过Prefetching来获取指令与数据
  • CacheLine缓存行
    • 每次访问的单位会根据系统与架构的不同而有所差异
    • 一般32或64个字节
    • 即使请求一个字节大小,实际上会得到CacheLine大小的缓存行数据
  • 在Cache缓存内
    • 可以将n个缓存行大小的缓存通过Direct-Map直接映射到同一逻辑缓存行
    • 逻辑缓存行可以对应n个物理行,来帮助最小化缓存行的抖动
      (抖动:挪动指针到每个物理缓存行的头)

【DOTS学习笔记】面向数据设计DOD_第1张图片


先看右侧下方的图:

  • CPU逻辑处理单元完成一条程序指令(其完成时间定义为CPU指令的cycle)
    • Fetch获得L1I指令缓存中的指令
    • Decode解码
    • Excution 执行
    • 执行完成后回写到L1D中

左侧的图:

  • CPU处理指令时,从不同的缓存Cache中获取数据的时间开销也不同
  • 获取的数据在某一级缓存没有命中时,向下一级缓存获取时
    • 花费的时间开销可能是数倍时间
    • 甚至是数量级的差异的时间开销

Cache的3C与3R


  • Compulsory misses:首次读取数据时,不可避免的Miss

  • Capacity misses:缓存空间不足,连续使用期间访问数据过多的话,无法保存所有活动的数据

  • Conflict misses:发生访问冲突时,由于数据映射到相同的缓存行,导致缓存的抖动

  • Rearrange 充血排列(代码、数据):更改布局以增加数据空间的局部性

  • Reduce减少(大小、缓存行读取):更小更只能的格式、压缩

  • Reuse重用(Cache lines):增加数据的时间(和空间)的局部性

面向数据设计需要思考的问题


  1. 哪些数据需要捆绑在一起,是一个概念还是有隐藏的含义
  2. 数据布局是如何设计的,AOS/SOA?支持 SIMD
  3. 目标平台内存的最小访问单位是多少,CPU各级缓存有多大?
  4. 数据多久需要一次,一帧一次,还是一帧多次,还是几乎不更新?
  5. 如何访问数据,随机/连续的还是stride或其他burst方式
  6. 总在修改数据还是只是读取数据,修改所有的内容,还是只修改一部分?
  7. 哪些数据设计对带宽的延迟影响大?

AOS


struct innerStruct
{
    float x;
    float y;
};

SOA


struct InnerArray
{
    float x[LEN];
    float y[LEN];
};

DOTS面向数据设计原则


  • 先设计,后编码
  • 为高效使用内存与缓存而设计
  • 为Blittable Data设计
  • 为普通情况设计
  • 拥抱迭代

你可能感兴趣的:(DOTS学习笔记,学习,缓存)