C++高性能并行编程与优化 - 课件 - 10 从稀疏数据结构到量化数据类型
用户态的实现。区别: std::mutex 的陷入等待会让操作系统挂起 该线程,以切换到另一个;而 tbb::spin_mutex 的陷入等待是通过 不断地 while (locked); 这样一个死循环不断轮询。对于我们高性 能计算而言 tbb::spin_mutex 更高效。其实 sizeof(std::mutex) = 40 字节,而 sizeof(tbb::spin_mutex) = 1 字节……0 码力 | 102 页 | 9.50 MB | 1 年前3Hello 算法 1.0.0b4 C++版
且可以灵活调整长度;但节点访问效率低、占 用内存较多。常见的链表类型包括单向链表、循环链表、双向链表。 ‧ 动态数组,又称列表,是基于数组实现的一种数据结构。它保留了数组的优势,同时可以灵活调整长 度。列表的出现极大地提高了数组的易用性,但可能导致部分内存空间浪费。 ‧ 下表总结并对比了数组与链表的各项特性与操作效率。 数组 链表 存储方式 连续内存空间 离散内存空间 数据结构长度 长度不可变 相较 SHA‑2 的实现开销更低、计算效率更高,但目前使用覆盖度不如 SHA‑2 系列。 MD5 SHA‑1 SHA‑2 SHA‑3 推出时 间 1992 1995 2002 2008 输出长 度 128 bits 160 bits 256 / 512 bits 224/256/384/512 bits 哈希冲 突 较多 较多 很少 很少 安全等 级 低,已被成功攻击 低,已被成功 ,?2 和 ? log ? 的数值比较接近,复杂度不占主 导作用;每轮中的单元计算操作数量起到决定性因素。 实际上,许多编程语言(例如 Java)的内置排序函数都采用了插入排序,大致思路为:对于长数组,采用基 于分治的排序算法,例如快速排序;对于短数组,直接使用插入排序。 虽然冒泡排序、选择排序和插入排序的时间复杂度都为 ?(?2) ,但在实际情况中,插入排序的使用频率显 著高于冒泡排序和选择排序。这是因为:0 码力 | 343 页 | 27.39 MB | 1 年前3Hello 算法 1.0.0b5 C++版
且可以灵活调整长度;但节点访问效率低、占 用内存较多。常见的链表类型包括单向链表、循环链表、双向链表。 ‧ 动态数组,又称列表,是基于数组实现的一种数据结构。它保留了数组的优势,同时可以灵活调整长 度。列表的出现极大地提高了数组的易用性,但可能导致部分内存空间浪费。 2. Q & A � 数组存储在栈上和存储在堆上,对时间效率和空间效率是否有影响? 栈内存分配由编译器自动完成,而堆内 SHA‑1 SHA‑2 SHA‑3 推出时 间 1992 1995 2002 2008 第 6 章 哈希表 hello‑algo.com 128 MD5 SHA‑1 SHA‑2 SHA‑3 输出长 度 128 bits 160 bits 256 / 512 bits 224/256/384/512 bits 哈希冲 突 较多 较多 很少 很少 安全等 级 低,已被成功攻击 低,已被成功 小时,?2 和 ? log ? 的数值比较接近,复杂度不占主 导作用;每轮中的单元操作数量起到决定性因素。 实际上,许多编程语言(例如 Java)的内置排序函数都采用了插入排序,大致思路为:对于长数组,采用基 于分治的排序算法,例如快速排序;对于短数组,直接使用插入排序。 虽然冒泡排序、选择排序和插入排序的时间复杂度都为 ?(?2) ,但在实际情况中,插入排序的使用频率显 著高于冒泡排序和选择排序,主要有以下原因。0 码力 | 377 页 | 30.69 MB | 1 年前3Hello 算法 1.0.0 C++版
基于数组实现的数据结构也称“静态数据结构”,这意味着此类数据结构在初始化后长度不可变。相对应地, 基于链表实现的数据结构也称“动态数据结构”,这类数据结构在初始化后,仍可以在程序运行过程中对其长 度进行调整。 � 如果你感觉物理结构理解起来有困难,建议先阅读下一章,然后再回顾本节内容。 3.2 基本数据类型 当谈及计算机中的数据时,我们会想到文本、图片、视频、语音、3D 模型等各种形式。尽管这些数据的组织 异或满足交换律,因此加法哈希和异或哈希无法区分内容相同但顺序不同的字符串,这可能会加剧哈希冲突, 并引起一些安全问题。 在实际中,我们通常会用一些标准哈希算法,例如 MD5、SHA‑1、SHA‑2 和 SHA‑3 等。它们可以将任意长 度的输入数据映射到恒定长度的哈希值。 近一个世纪以来,哈希算法处在不断升级与优化的过程中。一部分研究人员努力提升哈希算法的性能,另一 部分研究人员和黑客则致力于寻找哈希算法的安全性问题。表 6‑2 表 6‑2 常见的哈希算法 第 6 章 哈希表 hello‑algo.com 134 MD5 SHA‑1 SHA‑2 SHA‑3 推出时 间 1992 1995 2002 2008 输出长 度 128 bit 160 bit 256/512 bit 224/256/384/512 bit 哈希冲 突 较多 较多 很少 很少 安全等 级 低,已被成功攻击 低,已被成功攻0 码力 | 378 页 | 17.59 MB | 1 年前3C++高性能并行编程与优化 - 课件 - 12 从计算机组成原理看 C 语言指针
整数的加减乘除就要用特殊的指令来模拟了。 整数的表示范围受位数限制 • 8 位长的整数能表示的范围是 0 到 2^8-1 ,也就是 0 到 255 。 • 16 位长的整数能表示的范围是 0 到 2^16-1 ,也就是 0 到 65535 。 • 32 位长的整数能表示的范围是 0 到 2^32-1 ,也就是 0 到 4294967295 。 • 64 位长的整数能表示的范围是 0 到 2^64-1 ,也就是 0 size_t 还是 uint32_t ,那就无法表示超过 4GB 大小的数组了。 • 今日乳 ja 笑话: java 的字符串常量不能超过 65535 个字符,因为他们是用 uint16_t 表示字符串长 度。 • 因此对于表示”长度”、”大小”的用途,可以用 size_t 这个直观的名字,他和 uintptr_t 等价 。 • size_t 是标准库大量使用的用于表示大小的类型,例如 vector::size()0 码力 | 128 页 | 2.95 MB | 1 年前3Hello 算法 1.1.0 C++ 版
异或满足交换律,因此加法哈希和异或哈希无法区分内容相同但顺序不同的字符串,这可能会加剧哈希冲突, 并引起一些安全问题。 在实际中,我们通常会用一些标准哈希算法,例如 MD5、SHA‑1、SHA‑2 和 SHA‑3 等。它们可以将任意长 度的输入数据映射到恒定长度的哈希值。 近一个世纪以来,哈希算法处在不断升级与优化的过程中。一部分研究人员努力提升哈希算法的性能,另一 部分研究人员和黑客则致力于寻找哈希算法的安全性问题。表 6‑2 表 6‑2 常见的哈希算法 第 6 章 哈希表 hello‑algo.com 134 MD5 SHA‑1 SHA‑2 SHA‑3 推出时 间 1992 1995 2002 2008 输出长 度 128 bit 160 bit 256/512 bit 224/256/384/512 bit 哈希冲 突 较多 较多 很少 很少 安全等 级 低,已被成功攻击 低,已被成功攻 较小时,?2 和 ? log ? 的数值比较接近,复杂度不 占主导地位,每轮中的单元操作数量起到决定性作用。 实际上,许多编程语言(例如 Java)的内置排序函数采用了插入排序,大致思路为:对于长数组,采用基于 分治策略的排序算法,例如快速排序;对于短数组,直接使用插入排序。 虽然冒泡排序、选择排序和插入排序的时间复杂度都为 ?(?2) ,但在实际情况中,插入排序的使用频率显 著高于冒泡排序和选择排序,主要有以下原因。0 码力 | 379 页 | 18.47 MB | 1 年前3Hello 算法 1.2.0 简体中文 C++ 版
异或满足交换律,因此加法哈希和异或哈希无法区分内容相同但顺序不同的字符串,这可能会加剧哈希冲突, 并引起一些安全问题。 在实际中,我们通常会用一些标准哈希算法,例如 MD5、SHA‑1、SHA‑2 和 SHA‑3 等。它们可以将任意长 度的输入数据映射到恒定长度的哈希值。 近一个世纪以来,哈希算法处在不断升级与优化的过程中。一部分研究人员努力提升哈希算法的性能,另一 部分研究人员和黑客则致力于寻找哈希算法的安全性问题。表 6‑2 6‑2 常见的哈希算法 第 6 章 哈希表 www.hello‑algo.com 134 MD5 SHA‑1 SHA‑2 SHA‑3 推出时 间 1992 1995 2002 2008 输出长 度 128 bit 160 bit 256/512 bit 224/256/384/512 bit 哈希冲 突 较多 较多 很少 很少 安全等 级 低,已被成功攻击 低,已被成功攻 较小时,?2 和 ? log ? 的数值比较接近,复杂度不 占主导地位,每轮中的单元操作数量起到决定性作用。 实际上,许多编程语言(例如 Java)的内置排序函数采用了插入排序,大致思路为:对于长数组,采用基于 分治策略的排序算法,例如快速排序;对于短数组,直接使用插入排序。 虽然冒泡排序、选择排序和插入排序的时间复杂度都为 ?(?2) ,但在实际情况中,插入排序的使用频率显 著高于冒泡排序和选择排序,主要有以下原因。0 码力 | 379 页 | 18.48 MB | 9 月前3Hello 算法 1.0.0b1 C++版
的一个渐近上界,记为 ?(?) = ?(?(?)) Figure 2‑2. 函数的渐近上界 本质上看,计算渐近上界就是在找一个函数 ?(?) ,使得在 ? 趋向于无穷大时,?(?) 和 ?(?) 处于相同的增 长级别(仅相差一个常数项 ? 的倍数)。 2. 复杂度分析 hello‑algo.com 17 � 渐近上界的数学味儿有点重,如果你感觉没有完全理解,无需担心,因为在实际使用中我们只 需要会推算即可,数学意义可以慢慢领悟。 下可能失效,比如在输入数据量较小或时间复杂度相同时,无法精确对比算法效率的优劣性。 ‧「最差时间复杂度」使用大 ? 符号表示,即函数渐近上界,其反映当 ? 趋于正无穷时,?(?) 处于何种增 长级别。 ‧ 推算时间复杂度分为两步,首先统计计算操作数量,再判断渐近上界。 ‧ 常见时间复杂度从小到大排列有 ?(1) , ?(log ?) , ?(?) , ?(? log ?) , ?(?2) 出冒泡排序的计算开销约为插入排序的 3 倍。 插入排序运行速度快,并且具有原地、稳定、自适应的优点,因此很受欢迎。实际上,包括 Java 在内的许多 编程语言的排序库函数的实现都用到了插入排序。库函数的大致思路: ‧ 对于 长数组,采用基于分治的排序算法,例如「快速排序」,时间复杂度为 ?(? log ?) ; ‧ 对于 短数组,直接使用「插入排序」,时间复杂度为 ?(?2) ; 在数组较短时,复杂度中的常数项(即每轮0 码力 | 187 页 | 14.71 MB | 1 年前3Hello 算法 1.0.0b2 C++版
的一个渐近上界,记为 ?(?) = ?(?(?)) Figure 2‑2. 函数的渐近上界 本质上看,计算渐近上界就是在找一个函数 ?(?) ,使得在 ? 趋向于无穷大时,?(?) 和 ?(?) 处于相同的增 长级别(仅相差一个常数项 ? 的倍数)。 2. 复杂度分析 hello‑algo.com 17 � 渐近上界的数学味儿有点重,如果你感觉没有完全理解,无需担心,因为在实际使用中我们只 需要会推算即可,数学意义可以慢慢领悟。 实现,只需 1 个单元操作; 粗略估计,冒泡排序的计算开销约为插入排序的 3 倍,因此插入排序更受欢迎,许多编程语言(例如 Java)的 内置排序函数都使用到了插入排序,大致思路为: ‧ 对于 长数组,采用基于分治的排序算法,例如「快速排序」,时间复杂度为 ?(? log ?) ; ‧ 对于 短数组,直接使用「插入排序」,时间复杂度为 ?(?2) ; 虽然插入排序比快速排序的时间复杂度更高 右子数组任意元素。因此,接下来我们只需要排序两个子数组即可。 11. 排序算法 hello‑algo.com 170 Figure 11‑6. 哨兵划分步骤 � 快速排序的分治思想 哨兵划分的实质是将 一个长数组的排序问题 简化为 两个短数组的排序问题。 // === File: quick_sort.cpp === /* 元素交换 */ void swap(vector& nums, int 0 码力 | 197 页 | 15.72 MB | 1 年前3《深入浅出MFC》2/e
return (T)0; #0007 while (--exponent) result *= base; #0008 return result; #0009 } 对于长整数,函数应该是这样: 对于浮点数,我们应该...,对于复数,我们应该...。喔喔,为什么不能够把资料型别也变 成参数之一,在使用时指定呢?是的,这就是template 的妙用: 写成两行或许比较清楚: 消息进来,会有一个邦浦推动它前 进。消息如何进来,以及邦浦函数如何推动,都是属于Windows 程序设计的范畴,暂 时不管。我现在要仿真出消息的流动绕行路线-- 我常喜欢称之为消息的「二万五千里长 征」。 消息如果是从子类别流向父类别(纵向流动),那么事情再简单不过,整个Message Map 消息映射表已规划出十分明确的路线。但是正如上一节一开始我说的,MFC 之中用来处 理消息的C++ Name 所有的类别名称都由AppWizard 自动命名,如果你喜欢,也可以在AppWizard 的步骤六 改变之。这些类别名称可以很长很长(Windows 95 与Windows NT 均支持长档名)。每 个类别都对应一个.H(类别声明)和一个.CPP(类别定义)。 AppWizard 十分周到地为我们产生了一个README.TXT,对各个文件都有解释(图4- 8)。从激活AppWizard0 码力 | 1009 页 | 11.08 MB | 1 年前3
共 16 条
- 1
- 2