C++高性能并行编程与优化 - 课件 - 15 C++ 系列课:字符与字符串字符串的连接( + 运算符) • 错误: • 正确: C++14 新特性:自定义字面量后缀 • 不少同学就觉得这样好麻烦,其他语言都是直接 “ hello” 就是字符串类 型, C++ 还得套一层壳 string(“hello”) 才能变成安全封装的类型,才能用他 的成员函数。 • 因此, C++14 引入了一项缓解“键盘压力”的新特性: • 写 “ hello”_s 就相当于写 operator“”_s(“hello” 字符串没要求一定是 ‘ \0’ 结尾,字符串里是可以包含 ‘ \0’ 的。 C++14 新特性:自定义字面量后缀 • 如果你 using namespace std; 其实标准库已经自动帮你定义好了 “” s 后缀。 • 这里 “ hello”s 就等价于原本繁琐的 string(“hello”) 了。 C++14 新特性:自定义字面量后缀 • 如果你觉得 using namespace std; 太危险了不想用他。 这种预先规定好一些后缀,就只能是他们标准库的那 个 int32 ,不能自己定义了。 • 所以 cpp 之父曾经说,他设计 cpp11 的时候,是考虑“如何在对语言本身改动最小的情况下 ,尽量只在标准库里做手脚,尽可能只利用现有的语言特性,实现 cpp 的现代化。” • 例如 shared_ptr 可以通过利用语言本身的“拷贝构造函数”实现引用计数,没必要在编译器里 开洞。但“移动语义”这个概念在旧 cpp 里没有,所以这个是真正必要的语言本身的改动。0 码力 | 162 页 | 40.20 MB | 1 年前3
Zadig 产品使用手册DevOps 方案 Gitee 平台 GitLab 平台 局限性大、全流程安全性低 维护成本高 支持多个服务并行构建部署、产品级发布,可 灵活安全接入多个代码仓及周边工具链 开发 Zadig 核心特性: 运维 真正意义的持续交付:以工程师体验为核心,价值交付为理念,完成需求到发布的全路径。 测试 发布 洞察 一堆复杂脚本、维护成本极高 员工手工操作费时费力易出错 手动更新服务、手动打包、交付 项目负责人——分析项目各个环境的变化过程及效能短板 3 、 更多产品特性 Zadig 产品特性:开源 Zadig 的一切 云原生 CI/CD 、产研高效工程化协作、快速应对业务迭代 Zadig 产品特性:发布中心 编排组织、流程、内外部系统,管理代码、配置、数据变更流程,支持灰度组合策略 Zadig 产品特性:客户交付 面向大客户全天候响应、全地域升级部署,提供自运维和专用服务通道,实现稳定高效交付和服务保障 p s 领 域 的 领 军 企 业 。 旗 舰 产 品 云 原 生 D e v O p s 软 件 工 程 平 台 Z a d i g 正 在 成 为 数 字 化 软 件 研 发 的 新 标 配 , 帮 助 企 业 全 面 实 现 产 研 数 字 化 转 型 。 核 心 团 队 由 D e v O p s 领 域 云 计 算 工 程 技 术 专 家 和 高 级 工 程 师 为0 码力 | 52 页 | 22.95 MB | 1 年前3
C++高性能并行编程与优化 - 课件 - 08 CUDA 开启的 GPU 编程cn/docs/IO/51635/NVIDIA_CUDA_Programming_Guide_1.1_chs.pdf CUDA 编译器兼容 C++17 • CUDA 的语法,基本完全兼容 C++ 。包括 C+ +17 新特性,都可以用。甚至可以把任何一个 C++ 项目的文件后缀名全部改成 .cu ,都能编 译出来。 • 这是 CUDA 的一大好处, CUDA 和 C++ 的关 系就像 C++ 和 C 的关系一样,大部分都兼容 constexpr 通常都是一些可以内联的函数,数学计 算表达式之类的,一个个加上太累了,所以产生了这个 需求。 • 不过必须指定 --expt-relaxed-constexpr 这个选项才能 用这个特性,我们可以用 CMake 的生成器表达式来实 现只对 .cu 文件开启此选项(不然给到 gcc 就出错 了)。 • 当然, constexpr 里没办法调用 printf ,也不能用 __syncthreads 不够优化,但是至少能用。也就是要求:编译期指定的 版本 ≤ 运行时显卡的版本。 CMAKE_CUDA_ARCHITECTURES 会自动转换成 --gpu-code 等编 译 flag 版本号不要太新了 • 比如这里设置了 RTX3000 系列的架构版 本号 86 ,在 RTX2080 上就运行不出结 果。 • 最坑的是他不会报错!也不输出任何东西 !就像没有那个 kernel 一样!所以一定0 码力 | 142 页 | 13.52 MB | 1 年前3
C++高性能并行编程与优化 - 课件 - 03 现代 C++ 进阶:模板元编程auto func(); // 错误 C++ 特性:引用( int & ) • 众所周知, C++ 中有一种特殊的类型,叫做引用。只需要在原类型后面加一个 & 即可。 • 引用的本质无非是指针,当我们试图修改一个引用时,实际上是修改了原来的对象: 等价于 : 可见,和 C 语言的 int * 相比 无非是减少了 & 和 * 的麻烦 而已。 C++ 特性:常引用( int const & ) • 表达式:捕获 main 中的变量 • lambda 函数体中,还可以使用定义他的 main 函数中的变量,只需要把方括号 [] 改成 [&] 即可: • 函数可以引用定义位置所有的变量,这个 特性在函数式编程中称为闭包 (closure) 。 lambda 表达式:修改 main 中的变量 • [&] 不仅可以读取 main 中的变量,还可 以写入 main 中的变量,比如可以通过 性。 C++20 前瞻:函数也可以 auto , lambda 也可以• 如右图,两者的用法可以互换,更方便了 。 • 老师也欢迎同学们在作业中尝试 C++20 新特性,如果你们有相应的编译环境的话 。 • auto wrap(auto f) { • return [=] (auto ...args) { • return f(f, args. 0 码力 | 82 页 | 12.15 MB | 1 年前3
Zadig 面向开发者的云原生 DevOps 平台维护成本高 支持多个服务并行构建部署、产品级发布,可灵活 安全接入多个代码仓及周边工具链 Zadig 与现存 DevOps 方案对比 来自客户的评价: 2 Zadig 产品特性 Zadig 核心特性 面向开发者的云原生环境 灵活易用的高并发工作流 高效协同的测试管理 云原生 IDE 插件( VS CODE) 客观精准的效能洞察 强大免运维的模版库 • 自动生成面向开发、测试、运维角 - 飞书场景二: Gerrit + Zadig 方案 工程师体验 现状 Zadig Helm 方案 管理员 1. 上线服务,每个环境都配置 一份服务 values 文件 2. 创建新环境,准备 所有服务 values 文件 1. 从模板创建服务 -> 修改少量配置更新到所有环境 2. 创建环境,维护与环境相关的少量配置 开发 1. Rancher 手动更新服务 2. 调试更新配置 开发 debug 过程需要登录统一的内网主机使 用 Kubectl 操作,权限不可控,风险大。 对于新上项目,面对不同的使用场景,需要创建多 条 Jenkins Job ,配置繁琐,维护负担重。 与 传 统 的 业 务 研 发 不 同 , 电 动 汽 车 领 域 呈 现 新 的 软 件 产 品 交 付 形 态 , 交 付 场 景 复 杂 多 变 。 因 为 工 程 化 的 需 求 不0 码力 | 59 页 | 81.43 MB | 1 年前3
C++高性能并行编程与优化 - 课件 - 07 深入浅出访存优化cache[512]; • 当 CPU 读取一个地址时: • 缓存会查找和该地址匹配的条目。如果找到,则给 CPU 返 回缓存中的数据。如果找不到,则向主内存发送请求,等读 取到该地址的数据,就创建一个新条目。 • 在 x86 架构中每个条目的存储 64 字节的数据,这个条目 又称之为缓存行( cacheline )。 • 当访问 0x0048~0x0050 这 4 个字节时,实际会导致 0x0040~0x0080 cache[512]; • 当 CPU 写入一个地址时: • 缓存会查找和该地址匹配的条目。如果找到,则修改缓存 中该地址的数据。如果找不到,则创建一个新条目来存储 CPU 写的数据,并标记为脏( dirty )。 • 当读和写创建的新条目过多,缓存快要塞不下时,他会把 最不常用的那个条目移除,这个现象称为失效( invalid )。 如果那个条目是被标记为脏的,则说明是当时打算写入的 一下参数。 stream 的特点:不会读到缓存里 • 因为 _mm_stream_si32 会绕开缓存,直 接把数据写到内存,之后读取的话,反而 需要等待 stream 写回执行完成,然后重 新读取到缓存,反而更低效。 • 因此,仅当这些情况: 1. 该数组只有写入,之前完全没有读取过 。 2. 之后没有再读取该数组的地方。 • 才应该用 stream 指令。 4 倍矢量化的版本:0 码力 | 147 页 | 18.88 MB | 1 年前3
C++高性能并行编程与优化 - 课件 - 17 由浅入深学习 map 容器at(“key”) = val; // 写入键值为 “ key” 的元素,如果不存在,抛出异常 • 毕竟 [] 和 at() 只是返回引用,不管你是读取还是写入这个引用,函数本身的特性是不变的。 • 唯一的区别是等号在他后面,是往 K 对应的 V 里赋值。 • [] 创建在先, = 写入在后。成功写入了新建的元素。 • at 报错在先, = 写入在后。结果是报错了,没有写入。 • 所以 C++ 中写入元素,又得用 [] 才对, [] 在写入时又和多数语言的 [] 行为一致了。 • 这时 [] 自动默默创建的特性反而是个优点了,如果用了 at() 反而会在插入新键值时莫名 其妙报错。此外 [] 默默创建以后把值初始化为 0 的特性,由于调用者是 = val 赋值,所 以初始化也没用了,反正马上会写入 val 。 浅谈这种精分设计的原因 • 总结,要符合你熟悉的 Python val}) 不会覆盖,默默放弃 创建并写入值 m[key] = val 覆盖旧值 创建并写入值 m.insert_or_assign(key, val) 覆盖旧值 创建并写入值(更高效, C++17 新 增) m.at(key) = val 覆盖旧值 抛出 out_of_range 异常 判断 if (m.count(key)) 返回 1 返回 0 删除 m.erase(key) 删除这个值 默默放弃0 码力 | 90 页 | 8.76 MB | 1 年前3
新一代分布式高性能图数据库的构建 - 沈游人的学科带头人,我国高性能计算和存储系统等方面的 泰斗和先行者。 2021 年 3 月 25 日,海致科技与清华大学计算机科学与技术系共同建设高性能图计算院士专家工作站 。 高性能图计算是高性能计算、图计算两项技术融合产生的新的技术方向,满足人们对更大规模、更复 杂数据的实时处理和存储需求,是计算机领域竞争新战略制高点。 产学结合、协同创新,打造全球领先的国产自研图数据库 AtlasGraph ,培育世界级的图计算软硬件 验积累(接近客户需求) • 现有开源产品无法满足要求(受限于基础架构设计,优化性能有限) 新一代分布式图数据库需具备的特性 特性 信 雅 达 • 高可用 • 一致性(事 务) • 高性能 • 低资源消耗 • 易用 • 功能丰富 AtlasGraph 关键特性 云原生 Cloud-Native Graph Database 支持弹性伸缩,有 效利用硬件资源,高可用,高 可靠,故障自愈,低成本运维 Library • 集成 Jupyter Notebook 超参数自动优化 • 支持超参数自动调优,解放算 法科学家生产力,避免繁杂的 手动调参 海致图神经网络平台特点 Rust 语言特性助力构建高性能图数据库 01 利用 Rust Stream 进行数据流式 处理 02 03 协程和严格的内存安全性,编译 时捕获数据竞争和并发问题 异步物理算子实现,异步 IO 数 据获取0 码力 | 38 页 | 24.68 MB | 1 年前3
C++高性能并行编程与优化 - 课件 - 13 C++ STL 容器全解之 vectorconst &operator[](size_t i) const noexcept; vector 容器:构造函数 • 除了先指定大小再一个个构造之外,还可 以直接利用初始化列表( C++11 新特性) 在构造时就初始化其中元素的值。 • 例如创建具有 6, 1, 7, 4 四个元素的 vector : • vectora = {6, 1, 7, 4}; • 和刚刚先创建再赋值的方法相比更直观。 虑),所以指向元素的指针不会失效。他 只是会把数组的长度标记为新长度,后面 空闲出来那一段内存不会释放掉,继续留 在那里,直到 vector 对象被解构。 vector 容器:重新 resize 到原来尺寸也不会导致 data 失效 • 调用了 a.resize(2) 之后,数组的容量仍 然是 5 ,因此重新扩容到 5 是不需要重 新分配内存的,也就不会移动元素导致指 针失效。 vector 函数查询实际的最大容量 • 可以用 capacity() 函数查询已经分配内存的大小,即最大容 量。 • 而 size() 返回的其实是已经存储了数据的数组长度。 • 可以发现当 resize 指定的新长度一个超过原来的最大容量时 时,就会重新分配一段更大容量的内存来存储数组,只有这时 才会移动元素的位置( data 指针失效)。 • size_t capacity() const noexcept; 0 码力 | 90 页 | 4.93 MB | 1 年前3
C++高性能并行编程与优化 - 课件 - 12 从计算机组成原理看 C 语言指针的引用:无需手动 & 和 * • C++ 的引用类型 int& 本质无非是 int* 指 针。 • 区别在于: • 他不需要手动 & 来创建。 • 他不需要手动 * 来创建。 • 他无法重新赋值,指向新的变量。 • 他无法为空指针。 C 语言指针:可以为空指针( NULL ) • 指针可以指向一个变量,也可以什么都不指向 ,也就是空指针,也就是 NULL 。 • 在右边的例子中,我们用空指针来表示“调用者 语言思想的。 C 语言特性:函数声明为 T [] 类型的参数,实际上是 T * 类型 • 如果函数参数类型形如 • func(int arr[]) • func(int arr[6]) • 那么他其实就等价于: • func(int* arr) • 也就是说,给函数参数传入一个数组,实 际上等同于传入他的首地址指针,本质上 属于按引用传递。 C 语言特性:函数声明为 T [] 类型的参数,实际上是 随着数组的实际长度而变化。 • 对于动态数组请你手动传入数组长度作为参 数,对于 vector 请用 size() 成员函数。 对于这种自作聪明生搬硬套行为,我的评价是:邯郸学步 如何回避这一讨厌的 C 语言特性?我的建议 • 既然你用 int [] 做参数类型也会被 C 语言 自动替换成 int * ,我的建议是永远不要写 func(int arr[]) ,而是写 func(int* arr) ,索性0 码力 | 128 页 | 2.95 MB | 1 年前3
共 28 条
- 1
- 2
- 3













