C++高性能并行编程与优化 - 课件 - 15 C++ 系列课:字符与字符串
,内存管理与对象生命周期 ASCII 码 第 1 章 计算机如何表达字符 https://zh.wikipedia.org/wiki/ASCII 计算机如何表达字符 • 众所周知,计算机只能处理二进制 整数,字符要怎么办呢? • 于是就有了 ASCII 码表,他规定, 每个英文字符(包括大小写字母、 数字、特殊符号)都对应着一个整 数。在计算机里只要存储这个的整 数,就能代表这个字符了。 char 在 x86 架构是有符号的 (char = signed char) ,而在 arm 架构上则认为是无符号的 (char = unsigned char) ,因为他 认为“ arm 的指令集处理无符号 8 位整数更高效”,所以擅自把 char 魔改成无 符号的…… • 顺便一提, C++ 标准保证 char , signed char , unsigned char 是三个完全 不同的类型, 没什么好神秘的,他就是一个普通的字符。 • 仅仅只是 printf 和 scanf 这些特定的函数会对 % 特殊处理而已。 • 而 \ 比较厉害,他是编译器内部专门为他“开了个后门”。 • 编译器检测到字符串中出现 \ 就会把下一个字符特殊处理。 • 而 % ,编译器并不会特殊处理 % ,是 printf 函数内部在运行时处理了 % 的下一个字符。 • % 就像你和同学随手“拉钩”定下的约定,这是 printf 约定俗成的。0 码力 | 162 页 | 40.20 MB | 1 年前3C++高性能并行编程与优化 - 课件 - 07 深入浅出访存优化
其实,当程序顺序访问 a[0], a[1] 时, CPU 会智能地预测到你接下来可 能会读取 a[2] ,于是会提前给缓存发送一个读取指令,让他读取 a[2] 、 a[3] 。缓存在后台默默读取数据的同时, CPU 自己在继续处理 a[0] 的数据。这样等 a[0], a[1] 处理完以后,缓存也刚好读取完 a[2] 了,从而 CPU 不用等待,就可以直接开始处理 a[2] ,避免等待数据的 时候 CPU 简单来说:哪个索引最连续,就在后面,最不连 续的那个索引,就在最前面。 那么行主序其实是 XY 序,列主序其实是 YX 序。 如果你和盆友在电话里实在说不清楚,直接把扁 平化用的公式 (z * ny + y) * nx + x 通过文本信 息发给他也可,他看完就知道是 ZYX 序了。 主流程序都会用 YX 序, ZYX 序。 二维数组的遍历 • 二维数组在内存中的布局有 YX 序, XY 序。 • 二维数组的循环遍历也有 YX 实际上还是 YX 序,和静态数组 的 a[y][x] 一样的,指标出现的顺 序并无关紧要。 …… ndarray :访问越界问题 • 在物理仿真中,常常需要访问在一个元素附近的几个元素。图 像处理中用到的模糊操作,也需要向上下左右扩散 w 个单位。 • 这样假如当前元素正好在二维网格的边界上,那再往外索引 w 个单位就会超出数组的界限,导致出错。对此有多种解决办法 : 1. 使用 std::max(n0 码力 | 147 页 | 18.88 MB | 1 年前3新一代分布式高性能图数据库的构建 - 沈游人
等 100+ 公安机构,国家电网、 国信通产业集团等电力能源行业提供数据智能产品解决方案及长期服务。 海致专注为政府、金融、能源等客户提供大数据处理、分析、挖掘服务,在互 联网技术基础上,打造专业、易用的企业级大数据实战应用产品及解决方案。 北京中关村总部 武汉运维中心 深圳研发中心 上海应用中心 专注于数据智能技术赋能中国数字经济发展 海致高性能图计算院士专家工作站 郑纬民 - 月 25 日,海致科技与清华大学计算机科学与技术系共同建设高性能图计算院士专家工作站 。 高性能图计算是高性能计算、图计算两项技术融合产生的新的技术方向,满足人们对更大规模、更复 杂数据的实时处理和存储需求,是计算机领域竞争新战略制高点。 产学结合、协同创新,打造全球领先的国产自研图数据库 AtlasGraph ,培育世界级的图计算软硬件 生态体系,保持对全球科技竞争的战略均衡。 海致高性能图计算院士专家工作站 年中国电子学会科学技术奖科技进步一等奖 中国电子学会发布的《 2022 中国电子学会科学技术奖公告》,海 致星图与北京邮电大学、蚂蚁科技集团有限公司、中移动信息技术 有限公司联合研发的“大规模复杂异质图数据智能分析技术与规模化 应用”项目,斩获“科学技术奖科技进步一等奖”,这也是国内电子信 息领域的最高奖项。 该奖项由数十名院士评审,历经三轮,从三百余个申报项目中遴选 而出。由院士等组成的科技成果鉴定委员会认为:“该成果技术复杂0 码力 | 38 页 | 24.68 MB | 1 年前3C++高性能并行编程与优化 - 课件 - 02 现代 C++ 入门:RAII 内存管理
典型的例子包括,图形学某知名应用中, 可以简化函数具有多个返回值的处理。 • 和 std::tuple 相比,最大的好处是每个属性都有名字 ,不容易搞错。举个例子: • auto [hit, pos, ...] = intersect(...) • 每增加一个属性都要全部改一次代码。 • 更加 fancy 的写法: 编译器默认生成的构造函数:初始化列表(妙用,处理函数的复杂类型参 数) • 还有,函数的参数,如果是很复杂的类型 限于篇幅,其实构造函数还完全没讲完…… 下一讲继续完善我们刚才发明的 Vector 类 ! 也会详解 && 到底有哪些意思…… 来学智能指针压压惊 • 如果构造函数全家桶搞得你晕头转向了,那让我们来点(相对)简单的作为饭后甜点吧! C++98 :令人头疼的内存管理 • 在没有智能指针的 C++ 中,我们只能手 动去 new 和 delete 指针。这非常容易出 错,一旦马虎的程序员忘记释放指针,就 前,提前通过 p.get() 获取原始指针: 解决方案:提前获取原始指针(续) • 不过你得保证 raw_p 的存在时间不超过 p 的生命周期,否则会出现危险的空悬指 针。比如右边这样: 更智能的指针: shared_ptr • 使用起来很困难的原因,在于 unique_ptr 解决重复释放 的方式是禁止拷贝,这样虽然有效率高的优势,但导致使 用困难,容易犯错等。 • 相比之下, 牺牲效率换来自由度的0 码力 | 96 页 | 16.28 MB | 1 年前3C++高性能并行编程与优化 - 课件 - 08 CUDA 开启的 GPU 编程
上的编译器(通常是系统自带的编译 器比如 gcc 和 msvc )生成 CPU 部分的指令码。然后送到真 正的 GPU 编译器生成 GPU 指令码。最后再链接成同一个文件 ,看起来好像只编译了一次一样,实际上你的代码会被预处理很 多次。 • 他在 GPU 编译模式下会定义 __CUDA_ARCH__ 这个宏,利用 #ifdef 判断该宏是否定义,就可以判断当前是否处于 GPU 模式 ,从而实现一个函数针对 GPU Hello, world! 打印了三遍! • 原来,三重尖括号里的第二个参数决定着启动 kernel 时所用 GPU 的线程数量。 • GPU 是为并行而生的,可以开启很大数量的 线程,用于处理大吞吐量的数据。 获取线程编号 • 可以通过 threadIdx.x 获取当前线程的编 号,我们打印一下试试看。 • 这是 CUDA 中的特殊变量之一,只有在 核函数里才可以访问。 • 可以看到线程编号从 ),而每个板块具有的线程 数量( blockDim )则是固定的 128 。 • 因此,我们可以用 n / 128 作为 gridDim , 这样总的线程数刚好的 n ,实现了每个线程 负责处理一个元素。 边角料难题 • 但这样的话, n 只能是的 128 的整数倍 ,如果不是就会漏掉最后几个元素。 • 主要是 C 语言的整数除法 n / nthreads ,他是向下取整的,比如0 码力 | 142 页 | 13.52 MB | 1 年前3C++高性能并行编程与优化 - 课件 - 17 由浅入深学习 map 容器
通过实战案例来学习 STL 算法库 7. C++ 标准输入输出流 & 字符串格式化 8. traits 技术,用户自定义迭代器与算法 9. allocator ,内存管理与对象生命周期 10. C++ 异常处理机制的前世今生 我们都要认真鞋习哦 我们都要认真鞋习哦 第一章:读取与写入 我负责监督你鞋习 ! 我负责监督你鞋习 ! map 查找元素的两个接口 • map 提供了两个查找元素的接口,一曰 • val = m.at(“key”); // 读取键值为 “ key” 的元素,如果不存在,抛出异常 • 所以 [] 和 at() 唯一的区别,在于键值不存在这一特殊情况的处理方式。 • [] 默默创建。 • at() 抛出异常。 读取 map 元素 • mapm; • val = m[“key”]; • 读取键值为 “ key” 的元素,如果不存在,那就创建一个 一视同仁的接口就能处理这种罕见的情况,不过 Python 用一些 if 语句套一套一样可以。 深入理解 Python 中 [] 能自动区分是读是写的原理 • 写入要创建元素,而读取则要在元素不存在时出错,确实应该是两个不同的函数。 • 为什么 Python 不用区分读取和写入两个函数?只有统一的 [] ?因为 Python 作为老牌胶水语言,为了 用户体验做了些特殊处理。他的 ast 模块能自动识别 0 码力 | 90 页 | 8.76 MB | 1 年前3C++高性能并行编程与优化 - 课件 - 06 TBB 开启的并行编程之旅
Git 2.x (作业上传到 GitHub ) CUDA Toolkit 10.0 以上( GPU 专题) 第 0 章:从并发到并行 摩尔定律:停止增长了吗? • 晶体管的密度的确仍在指数增长,但处理器主 频却开始停止增长了,甚至有所下降。 • 很长时间之前我们就可以达到 2GHz ( 2001 年 8 月),根据 2003 年的趋势,在 2005 年 初我们就应该研发出 10GHz 的芯片。 神话与现实: 2 * 3GHz < 6GHz • 一个由双核组成的 3GHz 的 CPU 实际上提供了 6GHz 的处理能力,是吗? • 显然不是。甚至在两个处理器上同时运行两个线程也不见得可以获得两倍的性能。相似的 ,大多数多线程的应用不会比双核处理器的两倍快。他们应该比单核处理器运行的快,但 是性能毕竟不是线性增长。 • 为什么无法做到呢?首先,为了保证缓存一致性以及其他握手协议需要运行时间开销。在 • 并发:单核处理器,操作系统通过时间片调 度算法,轮换着执行着不同的线程,看起来 就好像是同时运行一样,其实每一时刻只有 一个线程在运行。目的:异步地处理多个不 同的任务,避免同步造成的阻塞。 • 并行:多核处理器,每个处理器执行一个线 程,真正的同时运行。目的:将一个任务分 派到多个核上,从而更快完成任务。 举个例子 • 并发:某互联网公司购置了一台单核处理 器的服务器,他正同时处理0 码力 | 116 页 | 15.85 MB | 1 年前3谈谈MYSQL那点事
拥有自己独立的缓冲池,能够缓存数据和索引 MySQL 架构设计—应用架构 强一致性 对读一致性的权衡,如果是对读写实时性要求非常高的话, 就将读写都放在 M1 上面, M2 只是作为 standby 。 比如,订单处理流程,那么对读需要强一致性,实时写实 时读,类似种涉及交易的或者动态实时报表统计的都要采 用这种架构模式 弱一致性 如果是弱一致性的话,可以通过在 M2 上面分担一些读压力 和流量,比如一些报表的读取以及静态配置数据的读取模块 MySQL MySQL 配置原则 配置原则 服务优化 服务优化 公共选项 公共选项 选项 缺省值 推荐值 说明 max_connections 100 1024 MySQL 服务器同时处理的数据库连接的最大 数量 query_cache_size 0 ( 不打开 ) 128M 查询缓存区的最大长度,按照当前需求,一 倍一倍增加,本选项比较重要 sort_buffer_size 512K SQL SQL 语句的编写 语句的编写 谨慎建立 谨慎建立 unique unique 类型的索引(唯一索引) 类型的索引(唯一索引) 大文本字段不建立为索引,如果要对大文本字段进行检索, 大文本字段不建立为索引,如果要对大文本字段进行检索, 可以考虑全文索引 可以考虑全文索引 频繁更新的列不适合建立过多索引 频繁更新的列不适合建立过多索引 应用优化 应用优化0 码力 | 38 页 | 2.04 MB | 1 年前3C++高性能并行编程与优化 - 课件 - 05 C++11 开始的多线程编程
0 以上( GPU 专题) 温馨提示: 1. 会用到第二讲( RAII 与智能指针)里的知识 2. 课件中一部分代码是基于 C++17 的 个人认为, C++11 中很多特性, 其实可以看做是为了支持多线程而 顺带引入的……如 chrono 、移动 、 lambda 、 RAII…… 第 0 章:时间 C 语言如何处理时间: time.h • long t0 = time(NULL); 每个线程共享同样的内存空间,开销比较小。 • 每个进程拥有独立的内存空间,因此开销更大。 • 对于高性能并行计算,更好的是多线程。 为什么需要多线程:无阻塞多任务 • 我们的程序常常需要同时处理多个任务。 • 例如:后台在执行一个很耗时的任务,比 如下载一个文件,同时还要和用户交互。 • 这在 GUI 应用程序中很常见,比如浏览 器在后台下载文件的同时,用户仍然可以 用鼠标操作其 了错误。 • 原来 std::thread 的实现背后是基于 pthread 的。 • 解决: CMakeLists.txt 里链接 Threads::Threads 即可: 有了多线程:异步处理请求 • 有了多线程的话,文件下载和用户交互分 别在两个线程,同时独立运行。从而下载 过程中也可以响应用户请求,提升了体验 。 • 可是发现一个问题:我输入完 pyb 以后, 他的确及时地和我交互了。但是用户交互0 码力 | 79 页 | 14.11 MB | 1 年前3C++高性能并行编程与优化 - 课件 - 11 现代 CMake 进阶指南
cmake-gui -B build 来启动 图形界面编辑各个缓存选项。 • 当然,直接用编辑器打开 build/CMakeCache.txt 修改后保存也是可以的。 • CMakeCache.txt 用文本存储数据,就是可供用 户手动编辑,或是被第三方软件打开并解析的。 缓存变量到底该如何更新?暴力解决:删 build 大法 用万能的“删 build 大法”当然是可以的。这样重新执行的时候缓存变量不存在, if (${MYVAR} MATCHES “Hello”) 会被翻译成 if (Hello MATCHES “Hello”) 但是因为找不到名为 Hello 的变量,所以会被直接当成普通的字符串来处理。 也就是 if (“Hello” MATCHES “Hello”) 从而会执行真分支,结果正常。 万一好巧不巧,正好定义了 Hello 这个变量呢? 然而假如存在 Hello 这个变量,其值为0 码力 | 166 页 | 6.54 MB | 1 年前3
共 27 条
- 1
- 2
- 3