C++高性能并行编程与优化 - 课件 - 07 深入浅出访存优化一次性读取到局部数组 ta 里,在局部迭代 16 次。 • 注意到局部数组是 64 大小,这包含了中心的 32 个元 素,还包含因为 jacobi 特性需要周围两个元素,导致 迭代 16 次就需要往边缘扩张的 16 个元素。 • 因为局部数组的大小远远小于一级缓存,这样迭代时 读写的带宽就是一级缓存的速度,几乎没有影响。 • 这里一次循环体直接相当于 16 次迭代,两次就完了。 但是可能加的有点过头变成0 码力 | 147 页 | 18.88 MB | 1 年前3
Hello 算法 1.0.0 C++版quadraticRecur(n - 1); } 图 2‑18 递归函数产生的平方阶空间复杂度 4. 指数阶 ?(2?) 指数阶常见于二叉树。观察图 2‑19 ,层数为 ? 的“满二叉树”的节点数量为 2? − 1 ,占用 ?(2?) 空间: // === File: space_complexity.cpp === /* 指数阶(建立满二叉树) */ TreeNode *buildTree(int 逻辑结构:线性与非线性 逻辑结构揭示了数据元素之间的逻辑关系。在数组和链表中,数据按照一定顺序排列,体现了数据之间的线 性关系;而在树中,数据从顶部向下按层次排列,表现出“祖先”与“后代”之间的派生关系;图则由节点 和边构成,反映了复杂的网络关系。 如图 3‑1 所示,逻辑结构可分为“线性”和“非线性”两大类。线性结构比较直观,指数据在逻辑关系上呈 线性排列;非线性结构则相反,呈非线性排列。 ‧ 线性 list」是一种线性数据结构,其中的每个元素都是一个节点对象,各个节点通过“引用”相连接。 引用记录了下一个节点的内存地址,通过它可以从当前节点访问到下一个节点。 链表的设计使得各个节点可以分散存储在内存各处,它们的内存地址无须连续。 第 4 章 数组与链表 hello‑algo.com 73 图 4‑5 链表定义与存储方式 观察图 4‑5 ,链表的组成单位是「节点 node」对象。每个节点都包含两项数据:节点的“值”和指向下一节0 码力 | 378 页 | 17.59 MB | 1 年前3
Hello 算法 1.1.0 C++ 版quadraticRecur(n - 1); } 图 2‑18 递归函数产生的平方阶空间复杂度 4. 指数阶 ?(2?) 指数阶常见于二叉树。观察图 2‑19 ,层数为 ? 的“满二叉树”的节点数量为 2? − 1 ,占用 ?(2?) 空间: // === File: space_complexity.cpp === /* 指数阶(建立满二叉树) */ TreeNode *buildTree(int 逻辑结构:线性与非线性 逻辑结构揭示了数据元素之间的逻辑关系。在数组和链表中,数据按照一定顺序排列,体现了数据之间的线 性关系;而在树中,数据从顶部向下按层次排列,表现出“祖先”与“后代”之间的派生关系;图则由节点 和边构成,反映了复杂的网络关系。 如图 3‑1 所示,逻辑结构可分为“线性”和“非线性”两大类。线性结构比较直观,指数据在逻辑关系上呈 线性排列;非线性结构则相反,呈非线性排列。 ‧ 线性 list)是一种线性数据结构,其中的每个元素都是一个节点对象,各个节点通过“引用”相连接。 引用记录了下一个节点的内存地址,通过它可以从当前节点访问到下一个节点。 链表的设计使得各个节点可以分散存储在内存各处,它们的内存地址无须连续。 第 4 章 数组与链表 hello‑algo.com 73 图 4‑5 链表定义与存储方式 观察图 4‑5 ,链表的组成单位是节点(node)对象。每个节点都包含两项数据:节点的“值”和指向下一节0 码力 | 379 页 | 18.47 MB | 1 年前3
Hello 算法 1.0.0b4 C++版return quadraticRecur(n - 1); } Figure 2‑12. 递归函数产生的平方阶空间复杂度 指数阶 ?(2?) 指数阶常见于二叉树。高度为 ? 的「满二叉树」的节点数量为 2? − 1 ,占用 ?(2?) 空间。 // === File: space_complexity.cpp === /* 指数阶(建立满二叉树) */ TreeNode *buildTree(int 逻辑结构:线性与非线性 「逻辑结构」揭示了数据元素之间的逻辑关系。在数组和链表中,数据按照顺序依次排列,体现了数据之间的 线性关系;而在树中,数据从顶部向下按层次排列,表现出祖先与后代之间的派生关系;图则由节点和边构 成,反映了复杂的网络关系。 逻辑结构通常分为“线性”和“非线性”两类。线性结构比较直观,指数据在逻辑关系上呈线性排列;非线 性结构则相反,呈非线性排列。 ‧ 线性数据结构:数组、链表、栈、队列、哈希表。 「链表 Linked List」是一种线性数据结构,其每个元素都是一个节点对象,各个节点之间通过指针连接,从 当前节点通过指针可以访问到下一个节点。由于指针记录了下个节点的内存地址,因此无需保证内存地址的 连续性,从而可以将各个节点分散存储在内存各处。 链表「节点 Node」包含两项数据,一是节点「值 Value」,二是指向下一节点的「指针 Pointer」,或称「引 用 Reference」。0 码力 | 343 页 | 27.39 MB | 1 年前3
Hello 算法 1.0.0b5 C++版quadraticRecur(n - 1); } 图 2‑18 递归函数产生的平方阶空间复杂度 4. 指数阶 ?(2?) 指数阶常见于二叉树。观察图 2‑19 ,高度为 ? 的“满二叉树”的节点数量为 2? − 1 ,占用 ?(2?) 空间: // === File: space_complexity.cpp === /* 指数阶(建立满二叉树) */ TreeNode *buildTree(int 逻辑结构:线性与非线性 逻辑结构揭示了数据元素之间的逻辑关系。在数组和链表中,数据按照顺序依次排列,体现了数据之间的线 性关系;而在树中,数据从顶部向下按层次排列,表现出祖先与后代之间的派生关系;图则由节点和边构成, 反映了复杂的网络关系。 如图 3‑1 所示,逻辑结构可被分为“线性”和“非线性”两大类。线性结构比较直观,指数据在逻辑关系上 呈线性排列;非线性结构则相反,呈非线性排列。 ‧ 线 素都是一个节点对象,各个节点通过“引用”相连接。 引用记录了下一个节点的内存地址,通过它可以从当前节点访问到下一个节点。 第 4 章 数组与链表 hello‑algo.com 70 链表的设计使得各个节点可以被分散存储在内存各处,它们的内存地址是无须连续的。 图 4‑5 链表定义与存储方式 观察图 4‑5 ,链表的组成单位是「节点 node」对象。每个节点都包含两项数据:节点的“值”和指向下一节0 码力 | 377 页 | 30.69 MB | 1 年前3
Hello 算法 1.2.0 简体中文 C++ 版quadraticRecur(n - 1); } 图 2‑18 递归函数产生的平方阶空间复杂度 4. 指数阶 ?(2?) 指数阶常见于二叉树。观察图 2‑19 ,层数为 ? 的“满二叉树”的节点数量为 2? − 1 ,占用 ?(2?) 空间: // === File: space_complexity.cpp === /* 指数阶(建立满二叉树) */ TreeNode *buildTree(int 逻辑结构:线性与非线性 逻辑结构揭示了数据元素之间的逻辑关系。在数组和链表中,数据按照一定顺序排列,体现了数据之间的线 性关系;而在树中,数据从顶部向下按层次排列,表现出“祖先”与“后代”之间的派生关系;图则由节点 和边构成,反映了复杂的网络关系。 如图 3‑1 所示,逻辑结构可分为“线性”和“非线性”两大类。线性结构比较直观,指数据在逻辑关系上呈 线性排列;非线性结构则相反,呈非线性排列。 ‧ 线性 素都是一个节点对象,各个节点通过“引用”相连接。 引用记录了下一个节点的内存地址,通过它可以从当前节点访问到下一个节点。 链表的设计使得各个节点可以分散存储在内存各处,它们的内存地址无须连续。 第 4 章 数组与链表 www.hello‑algo.com 73 图 4‑5 链表定义与存储方式 观察图 4‑5 ,链表的组成单位是节点(node)对象。每个节点都包含两项数据:节点的“值”和指向下一节0 码力 | 379 页 | 18.48 MB | 10 月前3
C++高性能并行编程与优化 - 课件 - 17 由浅入深学习 map 容器里面第一部分,也就是初始化语句: it = map.begin() 代表从最左节点开始出发。 • 第二部分,也就是判断是否退出的条件: it != map.end() 判断是否抵达最右节点的下一个 。 • 第三部分,也就是每次循环后执行的更新语句: ++it 会让迭代器往下一个节点移动。 • 所以人话就是:从根节点出发,不断向下一个移动,直到没有节点可遍历了。 • 而 for 里面的循环体,会对每个不同的 it 然后从程序员的黑盒视角看来,就是对于所有 map 中的 K-V 对执行了一遍循环体。 迭代器 operator++ 的移动方向 • 迭代器的 ++ 是中根遍历,先左子节点,然后根节点,最后右子节点。 • 为什么是中根遍历?因为刚刚说了二叉排序树的规则是:左子节点<父节点<右子节点。 • 这刚好是中根遍历的顺序,左中右。所以迭代器的 ++ 方向刚好是 K 越来越大的方向。 • 结论:遍历时,总是会按 K 从小到大的顺序。 1 待插入的数 4 5 8 7 set 查找为什么高效 • 刚刚的构建方法是平衡二叉树。而实际 set 中采用的是更为高效的红黑树。 • 区别就是每个节点上多挂了一个 bool 类型的 flag 变量,表示这个节点是红是黑。 • 总之这样三下五除二下来他的插入效率比平衡二叉树高出一个常数,但复杂度还是 O(logn) 。 • 红黑树的具体异同我会放到最后再细讲,一下子讲太深都睡着了,反正只有插入和删除的0 码力 | 90 页 | 8.76 MB | 1 年前3
C++高性能并行编程与优化 - 课件 - Zeno 中的现代 C++ 最佳实践 Zeno 节点系统 1.0 Zeno 节点系统 2.0 • Zeno 2.0 所在的分支: https://github.com/zenustech/zeno/tree/zeno2 • Zeno 1.0 所在的分支: https://github.com/zenustech/zeno/ Zeno 中的基本类型 • IObject 一切对象的公共基类。 • INode 一切节点的公共基类。 那个实现了擦除的包装类。 Zeno 节点系统 • 节点在 Zeno 中所扮演的角色,实际上相当于函数式编程中的函数。 • 节点输入若干个对象,并输出若干个对象。 Zeno 节点系统 • 节点的输出可以连线到另一个节点的输入上,相当于函数的调用和返回。 • 众多节点的组合,可以形成更强大的功能,这就是 Zeno 的 dataflow-programming 。 节点在 UI 中的表现 节点在 UI 中的表现 中的表现 节点在 UI 中的表现 节点在 UI 中的表现 main 函数第一个执行? • 众所周知, main 函数是 C/C++ 程序中 第一个执行的函数,是程序的入口点。 • 但,他真的是第一个执行的吗? 全局变量初始化的妙用 • 我们可以定义一个 int 类型全局变量 helper ,然后他的右边其实是可以写一个表达 式的,这个表达式实际上会在 main 函数之 前执行!0 码力 | 54 页 | 3.94 MB | 1 年前3
C++高性能并行编程与优化 - 课件 - 10 从稀疏数据结构到量化数据类型有了无边界的稀疏网格,再也不用担心二维数组要分配多大了。 坐标可以无限延伸,甚至可以是负数!比如 (-1,2) 等…… 他会自动在写入时分配 16x16 的子网格,称之为叶节点 (leaf node) ,而这里的 unordered_map 就是充当根节点 (root node) 。 图片解释稀疏的好处 传统稠密二维数组 无边界稀疏分块哈希表 此外,还是按需分配内存,即使被写入的部分奇形怪状也不会浪费内存。 图片解释:指针数组的原理 1 nul nul 2 3 nul nul nul nul 表示 nullptr (空指针) 图片解释:指针数组的稀疏 这样指针表中为 null 的部分,稠密叶节点的内存就省掉 了 垃圾回收 (garbage-collect) • 如果是运行的仿真,则液体可能会移动到 别的地方去。这时液体曾经存在过的地方 也仍然处于激活状态,可以每隔若干帧及 时释放掉这些不用的指针块以节省内存。 处理起来方便很多。 OpenVDB 的设计:如果用 SNode 来表示 • hash().pointer(5).pointer(4).dense(3) ZENO 中就大量使用了 OpenVDB ,并且以节点的形式提供给用户调用 • github.com/zenustech/zeno ZENO 中的流体仿真,就是基于 OpenVDB 的稀疏体积 • github.com/zenustech/zeno0 码力 | 102 页 | 9.50 MB | 1 年前3
Hello 算法 1.2.0 繁体中文 C++ 版array 数组 陣列 index 索引 索引 linked list 链表 鏈結串列 linked list node, list node 链表节点 鏈結串列節點 head node 头节点 頭節點 tail node 尾节点 尾節點 list 列表 串列 dynamic array 动态数组 動態陣列 hard disk 硬盘 硬碟 random‑access memory 二叉树 二元樹 tree node 树节点 樹節點 left‑child node 左子节点 左子節點 right‑child node 右子节点 右子節點 parent node 父节点 父節點 left subtree 左子树 左子樹 right subtree 右子树 右子樹 root node 根节点 根節點 leaf node 叶节点 葉節點 edge 边 邊 level0 码力 | 379 页 | 18.79 MB | 10 月前3
共 15 条
- 1
- 2













