C++高性能并行编程与优化 - 课件 - 05 C++11 开始的多线程编程C++11 开始的多线程编 程 by 彭于斌( @archibate ) 往期录播: https://www.bilibili.com/video/BV1fa411r7zp 课程 PPT 和代码: https://github.com/parallel101/course 高性能并行编程与优化 - 课程大纲 • 分为前半段和后半段,前半段主要介绍现代 C++ ,后半段主要介绍并行编程与优化。 GitHub ) CUDA Toolkit 10.0 以上( GPU 专题) 温馨提示: 1. 会用到第二讲( RAII 与智能指针)里的知识 2. 课件中一部分代码是基于 C++17 的 个人认为, C++11 中很多特性, 其实可以看做是为了支持多线程而 顺带引入的……如 chrono 、移动 、 lambda 、 RAII…… 第 0 章:时间 C 语言如何处理时间: time.h • long ,没有类型区分,导致很容易弄错单位,混淆时间点和时间段。 • 比如 t0 * 3 ,乘法对时间点而言根本是个无意义的计算,然而 C 语言把他们看做一样的 long 类型,从而容易让程序员犯错。 C++11 引入的时间标准库: std::chrono • 利用 C++ 强类型的特点,明确区分时间点与时间段,明确区分不同的时间单位。 • 时间点例子: 2022 年 1 月 8 日 13 点 07 分0 码力 | 79 页 | 14.11 MB | 1 年前3
C++高性能并行编程与优化 - 课件 - 02 现代 C++ 入门:RAII 内存管理C 语言 近代: C++98 引入 STL 容器库 近现代: C++11 引入了 {} 初始化表达式 近现代: C++11 引入了 range-based for-loop 如果想使用 for_each 这个算法模板呢? 我知道可以用 accumulate 啦!但是为了引出 lambda 表达式…… 近现代: C++11 引入了 lambda 表达式 现代: C++14 的 lambda *p{nullptr}; • 等价,都会零初始化。但是你不写那个空括号就会 变成内存中随机的值。 • 再比如: std::cout << int{}; 会打印出 0 编译器默认生成的构造函数:初始化列表(感谢 C++11 ) • 当一个类(和他的基类)没有定义任何构造函 数,这时编译器会自动生成一个参数个数和成 员一样的构造函数。 • 他会将 {} 内的内容,会按顺序赋值给对象的每 一个成员。 • 目的是为了方便程序员不必手写冗长的构造函 一旦我们定义了自己的构造函数,编译器就不会再生成默认的无参构造函数。 有自定义构造函数时仍想用默认构造函数: = default (续) • 如果还想让编译器自动生成默认的无参构造函数,可以用 C++11 新增的这个语法: 不过,据我所知,初始化列表 的那个构造函数就没办法通过 = default 语法恢复…… 编译器默认生成的构造函数:拷贝构造函数 • 除了无参和初始化列表构造函数外,编0 码力 | 96 页 | 16.28 MB | 1 年前3
C++20: An (Almost) Complete Overviewconcurrent_stack { struct Node { T t; shared_ptrnext; }; atomic_shared_ptr head; // in C++11: remove "atomic_" and use special // functions every time you touch head public: class reference shared_ptr p; }; auto find(T t) const { auto p = head.load(); // C++11: atomic_load(&head) while (p && p->t != t) p = p->next; return reference(move(p)); } } // C++11: atomic_compare_exchange_weak(&head, &p->next, p); } void pop_front() { auto p = head.load(); while (p && !head.compare_exchange_weak(p, p->next)) { } // C++11: atomic_ 0 码力 | 85 页 | 512.18 KB | 6 月前3
C++高性能并行编程与优化 - 课件 - 13 C++ STL 容器全解之 vectorint const &operator[](size_t i) const noexcept; vector 容器:构造函数 • 除了先指定大小再一个个构造之外,还可 以直接利用初始化列表( C++11 新特性) 在构造时就初始化其中元素的值。 • 例如创建具有 6, 1, 7, 4 四个元素的 vector : • vectora = {6, 1, 7, 4}; • 和刚刚先创建再赋值的方法相比更直观。 • vector a = {1, 2, 3}; • void push_back(int const &val); • void push_back(int &&val); // C++11 新增 vector 容器: pop_back • 而 pop_back 函数则是和 push_back 唱 反调,他是在数组的末尾删除一个数。例 如: • vector a = insert(const_iterator pos, int const &val); • iterator insert(const_iterator pos, int &&val); // C++11 vector 容器: insert 函数,插入位置是倒数第 2 个 • a.begin() 可以插入到开头位置。 • a.begin() + 1 可以插入到第二个元素位置。 • a.end() 0 码力 | 90 页 | 4.93 MB | 1 年前3
C++高性能并行编程与优化 - 课件 - Zeno 中的现代 C++ 最佳实践 初始化依然保证是原子的( C++11 起)。 • 这就是函数静态初始化 (func-static-init) 大法。 函数静态初始化可用于“懒汉单例模式” • 如右图。 • getMyClassInstance() 会在第一次调用时创 建 MyClass 对象,并返回指向他的引用。 • 根据 C++ 函数静态变量初始化的规则,之后 的调用不会再重复创建。 • 并且 C++11 也保证了不会多线程的危险, 在参数类型已经确定的情况下,例如: • void func(Descriptor const &desc); • 则 func(Descriptor(...)); • 与 func({...}); • 等价( C++11 起)。 Zeno 中一切节点的基类 • 输入输出全部存储在节点的 inputs 和 outputs 成员变量上。 • inputBounds 表示他连接在哪个节点的哪 个端口上,比如0 码力 | 54 页 | 3.94 MB | 1 年前3
C++高性能并行编程与优化 - 课件 - 03 现代 C++ 进阶:模板元编程• 这下基本学废!接下来看自动类型推导。 为什么需要自动类型推导( auto ) 没有 auto 的话,需要声明一个变量,必须重复一遍他的类型,非常麻烦 : 自动类型推导:定义变量 因此 C++11 引入了 auto ,使用 auto 定义的变量,其类型会自动根据等号右边的值来确定 : 自动类型推导:一些局限性 • 不过 auto 也并非万能,他也有很多限制。 • 因为需要等号右边的类型信息,所以没有 void(float) 。 • 这样 call_twice 会自动对每个不同的 func 类型编译一遍,从而允许编译器更好 地进行自动适配与优化。 函数式编程: lambda 表达式 • C++11 引入的 lambda 表达式允许我们 在函数体内创建一个函数,大大地方便了 函数式编程。 • 语法就是先一个空的 [] ,然后是参数列表 ,然后是 {} 包裹的函数体。 • 再也不用被迫添加一个全局函数了!0 码力 | 82 页 | 12.15 MB | 1 年前3
C++高性能并行编程与优化 - 课件 - 14 C++ 标准库系列课 - 你所不知道的 set 容器val); http://c.biancheng.net/view/7196.html glibc 中 pair 的定义 • pair 类似于 python 里的元组,不过固定只能有两个元素,自从 C++11 引 入了能支持任意多元素的 tuple 以来,就没 pair 什么事了……但是为了兼 容 pair 还是继续存在着。 pair 是个模板类,根据尖括号里你给定的类型来 替换这里的 _T1 和 _T2 指向第一个大于等于 x 的元素 √ √ × upper_bound(x) 指向第一个大于 x 的元素 √ √ × equal_range(x) 所有等于 x 的元素所组成的区 间 √ √ √ C++11 新增: unordered_set 容器 • set 会让元素从小到大排序 。 • 而 unordered_set 不会排序 ,里面的元素都是完全随机 的顺序,和插入的顺序也不 一样。虽然你可能注意到这0 码力 | 83 页 | 10.23 MB | 1 年前3
C++高性能并行编程与优化 - 课件 - 08 CUDA 开启的 GPU 编程,不然早该换成 C++11 的 std::tuple 和 C++17 的 structual-binding 语法了……反正我是不喜欢用他的迭代器这一套,简单的问题反而复杂化。 • 怪不得王鑫磊在 ZPC 里要自己造轮子哦,虽然是 C++03 ,总感觉是几百年前的编程语言。 • 现在很多“老年”教材对 cpp 的认识也停留在 C++03 , B 站 / 油管偶尔翻出几个介绍 C++11 新特性的视频已经算很先进很前卫了,然而现在0 码力 | 142 页 | 13.52 MB | 1 年前3
whats new in visual studioComing next for C++23 • STL • Standard library modules • Coroutines 💡 C++98* * with /permissive- 💡 C++11 💡 C++14 💡 C++17 💡 C++20* *awaiting DR resolution 🐱🏍�C++23 with /std:c++latest Visual0 码力 | 42 页 | 19.02 MB | 6 月前3
C++高性能并行编程与优化 - 课件 - 10 从稀疏数据结构到量化数据类型读取:如果不存在,则读到 0 写入:如果不存在,则创建该表项 用 unordered_map 来存储 map 基于红黑树,会按照键值排序,需要键值具有 operator< 重载,复杂度 O(logn) C++11 新增的 unordered_map 基于哈希表,不保证顺序但更高效,需要键值能被哈希,复杂度 O(1) 用 unordered_map 按 16x16 分块存储 分块能减少 unordered_map0 码力 | 102 页 | 9.50 MB | 1 年前3
共 14 条
- 1
- 2













