C++高性能并行编程与优化 - 课件 - 07 深入浅出访存优化页对齐的重要性 • 为什么要 4KB ?原来现在操作系统管理内存是用分页 ( page ),程序的内存是一页一页贴在地址空间中的, 有些地方可能不可访问,或者还没有分配,则把这个页设 为不可用状态,访问他就会出错,进入内核模式。 • 因此硬件出于安全,预取不能跨越页边界,否则可能会触 发不必要的 page fault 。所以我们选用页的大小,因为本 来就不能跨页顺序预取,所以被我们切断掉也无所谓。 * 0.5 • 不妨带入 (1) 式到 (2) 式,得到: • a’’[i] = (a[i - 2] + a[i + 2]) * 0.25 + a[i] * 0.5 • 我们得到了求出两次迭代后状态的公式。这样 就可以在一个循环体内实现两次迭代的效果! 从而快了 2 倍。 动画演示 a a’ a’’ 局部数组,一步抵 16 步 • 一次性读取到局部数组 ta 里,在局部迭代 16 众所周知,内存是一维的,因此任何二维数组,都必须被扁平化,才能储存在内存中。 • 对于 float a[3][4] 编译器实际上会把他变成一维数组 float a[3*4] ,然后把 a[i][j] 翻译为 a[i * 4 + j] 。 C++ 静态数组 • arraya; 可以在栈上分配有 n 个元素的一维数组。 • 通过 a[i] 访问第 i 个元素。 • array 0 码力 | 147 页 | 18.88 MB | 1 年前3
《深入浅出MFC》2/e程序设计》)之后,陆陆续续我 收到了许多许多的大陆读者来函。其中对我的赞美、感谢、关怀、殷殷垂询, 让我非常感动。 《深入浅出MFC》2/e 早已于1998/05 于台湾出版。之所以迟迟没有授权给大 陆进行简体翻译,原因我曾于回复读者的时候说过很多遍。我在此再说一次。 1998 年中,本书之发行公司松岗(UNALIS)即希望我授权简体版,然因当时 我已在构思3/e,预判3/e 繁体版出版时,2/e 简体版恐怕还未能完成。老是让 C++ 和Hou 的Dissecting MFC 是通往MFC Programming 的皇家大道』。 ii 香港. lnlo@hkstart.com 我是你的一位读者,住在香港。我刚买了你翻译的Inside Visual C++ 4.0(中文版)。在此 之前我买了你的另一本书深入浅出MFC。在读了深入浅出MFC 前面50~70 页之后,我 想我错买了一本很艰深的书籍。我需要的是一本教我如何利用MFC 以后看,哇,那种感觉真是过瘾。 桃园Shelly 在书局看到您多本书籍,实在忍不住想告诉您我的想法!我是来谢谢您的。怎么说呢?姑且 不论英文能力,看原文书总是没有看中文书来得直接啊!您也知晓的,许多翻译书中的每个 中文字都看得懂,但是整段落就是不知他到底在说啥!因此看到书的作者是您,感觉上就是 一个品质上的保证,必定二话不说,抱回家啰!虽然眼前用不到,但是翻翻看,大致了解一 下,待有空时或是工作上需要时再好好细读。0 码力 | 1009 页 | 11.08 MB | 1 年前3
C++高性能并行编程与优化 - 课件 - 11 现代 CMake 进阶指南TBB 但是找不到 Eigen3 的情况。 第 6 章:输出与变量 在运行 cmake -B build 时,打印字符串(用于调试) message(STATUS “...”) 表示信息类型是状态信息,有 -- 前缀 message(WARNING “...”) 表示是警告信息 message(AUTHOR_WARNING “...”) 表示是仅仅给项目作者看的警 告信息 AUTHOR_WARNING ${MYVAR} 这个变量。如果有这个变量则会被替换为变量的值来进行接下来的比较, 否则保持原来字符串不变。 如果我加了 ${} 会怎么样呢? if (${MYVAR} MATCHES “Hello”) 会被翻译成 if (Hello MATCHES “Hello”) 但是因为找不到名为 Hello 的变量,所以会被直接当成普通的字符串来处理。 也就是 if (“Hello” MATCHES “Hello”) 从而会执行真分支,结果正常。 万一好巧不巧,正好定义了 Hello 这个变量呢? 然而假如存在 Hello 这个变量,其值为 “ world” 。 那么 if (${MYVAR} MATCHES “Hello”) 会被翻译成 if (Hello MATCHES “Hello”) 而因为 Hello 这个变量名存在,所以会被(出于历史原因的) if 进一步求值: if (“world” MATCHES “Hello”)0 码力 | 166 页 | 6.54 MB | 1 年前3
Hello 算法 1.0.0b1 C++版2.2. 行文风格约定 标题后标注 * 的是选读章节,内容相对较难。如果你的时间有限,建议可以先跳过。 文章中的重要名词会用「括号」 标注,例如「数组 Array」 。建议记住这些名词,包括英文翻译,以便后续阅 读文献时使用。 重点内容、总起句、总结句会被 加粗,此类文字值得特别关注。 专有名词和有特指含义的词句会使用“双引号” 标注,以避免歧义。 0. 写在前面 hello‑algo tmp; count += 3; // 元素交换包含 3 个单元操作 } } } return count; } 指数阶 ?(2?) � 生物学科中的“细胞分裂”即是指数阶增长:初始状态为 1 个细胞,分裂一轮后为 2 个,分裂 两轮后为 4 个,⋯⋯,分裂 ? 轮后有 2? 个细胞。 指数阶增长得非常快,在实际应用中一般是不能被接受的。若一个问题使用「暴力枚举」求解的时间复杂度是 Figure 7‑7. 平衡二叉树 7.1.4. 二叉树的退化 当二叉树的每层的结点都被填满时,达到「完美二叉树」;而当所有结点都偏向一边时,二叉树退化为「链 表」。 ‧ 完美二叉树是一个二叉树的“最佳状态”,可以完全发挥出二叉树“分治”的优势; ‧ 链表则是另一个极端,各项操作都变为线性操作,时间复杂度退化至 ?(?) ; Figure 7‑8. 二叉树的最佳与最二叉树的最佳和最差结构差情况0 码力 | 187 页 | 14.71 MB | 1 年前3
Hello 算法 1.0.0b4 C++版行文风格约定 ‧ 标题后标注 * 的是选读章节,内容相对困难。如果你的时间有限,建议可以先跳过。 ‧ 文章中的重要名词会用「」 括号标注,例如「数组 Array」 。请务必记住这些名词,包括英文翻译,以 便后续阅读文献时使用。 ‧ 加粗的文字 表示重点内容或总结性语句,这类文字值得特别关注。 ‧ 专有名词和有特指含义的词句会使用“双引号” 标注,以避免歧义。 ‧ 涉及到编程语言之间不一致的名词,本书均以 以将上述查字典的一系列操作看作是「二分查找」算法。 例二:整理扑克。我们在打牌时,每局都需要整理扑克牌,使其从小到大排列,实现流程如下: 1. 将扑克牌划分为“有序”和“无序”两部分,并假设初始状态下最左 1 张扑克牌已经有序。 2. 在无序区间抽出一张扑克牌,插入至有序区间的正确位置;完成后最左 2 张扑克已经有序。 3. 在无序区间抽出一张扑克牌,插入至有序区间的正确位置;完成后最左 3 tmp; count += 3; // 元素交换包含 3 个单元操作 } } } return count; } 指数阶 ?(2?) � 生物学的“细胞分裂”是指数阶增长的典型例子:初始状态为 1 个细胞,分裂一轮后变为 2 个,分裂两轮后变为 4 个,以此类推,分裂 ? 轮后有 2? 个细胞。 指数阶增长非常迅速,在实际应用中通常是不可接受的。若一个问题使用「暴力枚举」求解的时间复杂度为0 码力 | 343 页 | 27.39 MB | 1 年前3
Hello 算法 1.0.0b2 C++版2.2. 行文风格约定 标题后标注 * 的是选读章节,内容相对较难。如果你的时间有限,建议可以先跳过。 文章中的重要名词会用「括号」 标注,例如「数组 Array」 。建议记住这些名词,包括英文翻译,以便后续阅 读文献时使用。 重点内容、总起句、总结句会被 加粗,此类文字值得特别关注。 专有名词和有特指含义的词句会使用“双引号” 标注,以避免歧义。 0. 写在前面 hello‑algo tmp; count += 3; // 元素交换包含 3 个单元操作 } } } return count; } 指数阶 ?(2?) � 生物学科中的“细胞分裂”即是指数阶增长:初始状态为 1 个细胞,分裂一轮后为 2 个,分裂 两轮后为 4 个,⋯⋯,分裂 ? 轮后有 2? 个细胞。 指数阶增长得非常快,在实际应用中一般是不能被接受的。若一个问题使用「暴力枚举」求解的时间复杂度是 Figure 7‑7. 平衡二叉树 7.1.4. 二叉树的退化 当二叉树的每层的结点都被填满时,达到「完美二叉树」;而当所有结点都偏向一边时,二叉树退化为「链 表」。 ‧ 完美二叉树是一个二叉树的“最佳状态”,可以完全发挥出二叉树“分治”的优势; ‧ 链表则是另一个极端,各项操作都变为线性操作,时间复杂度退化至 ?(?) ; Figure 7‑8. 二叉树的最佳与最二叉树的最佳和最差结构差情况0 码力 | 197 页 | 15.72 MB | 1 年前3
Hello 算法 1.0.0 C++版如何使用本书 � 为了获得最佳的阅读体验,建议你通读本节内容。 0.2.1 行文风格约定 ‧ 标题后标注 * 的是选读章节,内容相对困难。如果你的时间有限,可以先跳过。 ‧ 重要专有名词及其英文翻译会用「」 括号标注,例如「数组 array」 。建议记住它们,以便阅读文献。 ‧ 专有名词和有特指含义的词句会使用“引号” 标注,以避免歧义。 ‧ 重要名词、重点内容和总结性语句会 加粗,这类文字值得特别关注。 例二:整理扑克。我们在打牌时,每局都需要整理手中的扑克牌,使其从小到大排列,实现流程如图 1‑2 所 示。 第 1 章 初识算法 hello‑algo.com 12 1. 将扑克牌划分为“有序”和“无序”两部分,并假设初始状态下最左 1 张扑克牌已经有序。 2. 在无序部分抽出一张扑克牌,插入至有序部分的正确位置;完成后最左 2 张扑克已经有序。 3. 不断循环步骤 2. ,每一轮将一张扑克牌从无序部分插入至有序部分,直至所有扑克牌都有序。 tmp; count += 3; // 元素交换包含 3 个单元操作 } } } return count; } 4. 指数阶 ?(2?) 生物学的“细胞分裂”是指数阶增长的典型例子:初始状态为 1 个细胞,分裂一轮后变为 2 个,分裂两轮后 变为 4 个,以此类推,分裂 ? 轮后有 2? 个细胞。 图 2‑11 和以下代码模拟了细胞分裂的过程,时间复杂度为 ?(2?) : 第 20 码力 | 378 页 | 17.59 MB | 1 年前3
Hello 算法 1.0.0b5 C++版1 行文风格约定 ‧ 标题后标注 * 的是选读章节,内容相对困难。如果你的时间有限,建议可以先跳过。 ‧ 专有名词和有特指含义的词句会使用“双引号” 标注,以避免歧义。 ‧ 重要专有名词及其英文翻译会用「」 括号标注,例如「数组 array」 。建议记住它们,以便阅读文献。 ‧ 加粗的文字 表示重点内容或总结性语句,这类文字值得特别关注。 ‧ 当涉及到编程语言之间不一致的名词时,本书均以 Python 字典的一系列操作看作是“二分查找”。 例二:整理扑克。我们在打牌时,每局都需要整理扑克牌,使其从小到大排列,实现流程如图 1‑2 所示。 1. 将扑克牌划分为“有序”和“无序”两部分,并假设初始状态下最左 1 张扑克牌已经有序。 2. 在无序部分抽出一张扑克牌,插入至有序部分的正确位置;完成后最左 2 张扑克已经有序。 3. 不断循环步骤 2. ,每一轮将一张扑克牌从无序部分插入至有序部分,直至所有扑克牌都有序。 tmp; count += 3; // 元素交换包含 3 个单元操作 } } } return count; } 4. 指数阶 ?(2?) 生物学的“细胞分裂”是指数阶增长的典型例子:初始状态为 1 个细胞,分裂一轮后变为 2 个,分裂两轮后 变为 4 个,以此类推,分裂 ? 轮后有 2? 个细胞。 图 2‑11 和以下代码模拟了细胞分裂的过程,时间复杂度为 ?(2?) 。 // ===0 码力 | 377 页 | 30.69 MB | 1 年前3
C++高性能并行编程与优化 - 课件 - 15 C++ 系列课:字符与字符串这些整数,而 8 位整数的表示范围是 2^8 也就是 0~255 ,足以表示所有 ASCII 字符了(多余的部分实际上被用于表示 中文)。 • char 和整数无异,例如 ‘ a’ 实际上会被编译器翻译成他对应的 ASCII 码: 97 。写 ‘ a’ 和写 (char)97 是完全一样的,方便阅读的语法糖而已。 “char 即整数”思想应用举例 “char 即整数”思想应用举例 C 语言帮手函数 所以这就是为什么 GCC 标准库把成员变量 _M_p 挪到了一个 _Alloc_hider 里,而 让 _Alloc_hider 又继承 allocator 。就是为了在 allocator 为空类的时候(无状态分 配器),能让 allocator 不必占据额外的空间。 • 问题:既然 allocator 往往都是个空类( std::allocator默认就是空类,只有几个 成员函数负责调用 operator operator new 和 operator delete ),为什么还要把 allocator 对 象存到 string 对象里,最后还要搞什么空基类优化防止他浪费空间,多此一举? • 因为最近开始流行“有状态分配器”了,侯杰老师显然不知道这一点,在他的 STL 课 里,讲到这部分源码时,还吐槽“为什么多此一举”,幸好小彭老师看出了这一点。 有无空基类优化的对比 _M_dataplus._M_p _M_dataplus 0 码力 | 162 页 | 40.20 MB | 1 年前3
Hello 算法 1.1.0 C++ 版例二:整理扑克。我们在打牌时,每局都需要整理手中的扑克牌,使其从小到大排列,实现流程如图 1‑2 所 示。 第 1 章 初识算法 hello‑algo.com 12 1. 将扑克牌划分为“有序”和“无序”两部分,并假设初始状态下最左 1 张扑克牌已经有序。 2. 在无序部分抽出一张扑克牌,插入至有序部分的正确位置;完成后最左 2 张扑克已经有序。 3. 不断循环步骤 2. ,每一轮将一张扑克牌从无序部分插入至有序部分,直至所有扑克牌都有序。 tmp; count += 3; // 元素交换包含 3 个单元操作 } } } return count; } 4. 指数阶 ?(2?) 生物学的“细胞分裂”是指数阶增长的典型例子:初始状态为 1 个细胞,分裂一轮后变为 2 个,分裂两轮后 变为 4 个,以此类推,分裂 ? 轮后有 2? 个细胞。 图 2‑11 和以下代码模拟了细胞分裂的过程,时间复杂度为 ?(2?) : 第 2 ) = ? 哈希函数下,每个元素对应唯一的桶索引,这与数组等价。然而,输入空间通常远大于输出空 间(数组长度),因此哈希函数的最后一步往往是对数组长度取模。换句话说,哈希表的目标是将一个较大的 状态空间映射到一个较小的空间,并提供 ?(1) 的查询效率。 Q:哈希表底层实现是数组、链表、二叉树,但为什么效率可以比它们更高呢? 首先,哈希表的时间效率变高,但空间效率变低了。哈希表有相当一部分内存未使用。0 码力 | 379 页 | 18.47 MB | 1 年前3
共 20 条
- 1
- 2













