C++高性能并行编程与优化 - 课件 - 16 现代 CMake 模块化项目管理指南
现代 CMake 模块化项目管理指南 彭于斌( @archibate ) 课件 & 源码: https://github.com/parallel101/course 往期录播: https://space.bilibili.com/263032155 找不到头文 件怎么办呀 CMake Cookbook 小彭老师建议 : ~~-·~·~-·~ -~·-·~·- 第一章:文件 / / 目录组织规范 基于 CMake 的 C/C++ 项目,如何优雅地、模块化地组织大量源文件 ? 推荐的目录组织方式 • 目录组织格式: • 项目名 /include/ 项目名 / 模块名 .h • 项目名 /src/ 模块名 .cpp • CMakeLists.txt 中写: • target_include_directories( 项目名 PUBLIC include) • 源码文件中写: 分别在各自的目录下有自己的 CMakeLists.txt 。 二、根项目的 CMakeLists.txt 配置 • 在根项目的 CMakeLists.txt 中,设置了默 认的构建模式,设置了统一的 C++ 版本 等各种选项。然后通过 project 命令初始 化了根项目。 • 随后通过 add_subdirectory 把两个子项 目 pybmain 和 biology 添加进来(顺序 无关紧要),这会调用0 码力 | 56 页 | 6.87 MB | 1 年前3现代C++ 教程:高速上手C++11/14/17/20
变量及其初始化 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 if/switch 变量声明强化 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 初始化列表 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16 结构化绑定 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 2.3 类型推导 . . 38 右值引用和左值引用 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39 移动语义 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41 完美转发0 码力 | 83 页 | 2.42 MB | 1 年前3C++高性能并行编程与优化 - 课件 - 15 C++ 系列课:字符与字符串
容器全家桶及其妙用举例 5. 函子 functor 与 lambda 表达式知多少 6. 通过实战案例来学习 STL 算法库 7. C++ 标准输入输出流 & 字符串格式化 8. traits 技术,用户自定义迭代器与算法 9. allocator ,内存管理与对象生命周期 ASCII 码 第 1 章 计算机如何表达字符 https://zh.wikipedia 给出警告),但是运行结果不对,或者还有可能崩溃。 泛型的 iostream 应运而生 • 得益于 C++ 的重载技术, cout 不用你手动指定类型,他 会自动识别参数的类型,帮你调用相应的格式化函数。 c_str 和 data 的区别 • s.c_str() 保证返回的是以 0 结尾的字符串首地址指针,总长度为 s.size() + 1 。 • s.data() 只保证返回长度为 s cpp11 的时候,是考虑“如何在对语言本身改动最小的情况下 ,尽量只在标准库里做手脚,尽可能只利用现有的语言特性,实现 cpp 的现代化。” • 例如 shared_ptr 可以通过利用语言本身的“拷贝构造函数”实现引用计数,没必要在编译器里 开洞。但“移动语义”这个概念在旧 cpp 里没有,所以这个是真正必要的语言本身的改动。 • 而 java 就是在语言层面,直接在 jvm 里引入了引用计数,宣称“一切皆对象”,虽然方便了0 码力 | 162 页 | 40.20 MB | 1 年前3C++高性能并行编程与优化 - 课件 - Zeno 中的现代 C++ 最佳实践
html 类型擦除利用的是 C++ 模板的惰性实例化, Java 的泛型是做不到滴 • 由于 C++ 模板惰性编译的特性,这个擦除掉的表达式会在你实例化 AnimalWrapper的时候 自动对 T 进行编译。这意味着如果你给他一个不具有一个名为 speak 成员函数的类(比如这里 的 Phone 类只有 play 函数)就会在实例化的那行出错。 • 注意:这里的 m_inner.speak() speak() 只是一个例子,其实不一定是成员函数,完全可以是 std::sort(m_inner.begin(), m_inner.end()) 之类的任意表达式,只要语义上通过,就可以实例化。 • (把 sort 封装成虚函数,留作回家作业) Zeno 中对 OpenVDB 的类型擦除 • 结合类型擦除技术,自动虚克隆技术。 • VDBGrid 作为所有网格类的基类提供各个 操作做为虚函数, C/C++ 程序中 第一个执行的函数,是程序的入口点。 • 但,他真的是第一个执行的吗? 全局变量初始化的妙用 • 我们可以定义一个 int 类型全局变量 helper ,然后他的右边其实是可以写一个表达 式的,这个表达式实际上会在 main 函数之 前执行! • 全局变量的初始化会在 main 之前执行,这实 际上是 C++ 标准的一部分,我们完全可以放 心利用这一点来执行任意表达式。 0 码力 | 54 页 | 3.94 MB | 1 年前3C++高性能并行编程与优化 - 课件 - 02 现代 C++ 入门:RAII 内存管理
com/doc) - [GitHub 官方文档 ](https://docs.github.com/en) 古代: C 语言 近代: C++98 引入 STL 容器库 近现代: C++11 引入了 {} 初始化表达式 近现代: C++11 引入了 range-based for-loop 如果想使用 for_each 这个算法模板呢? 我知道可以用 accumulate 啦!但是为了引出 lambda 函数分离了声明和定 义,实现在另一个文件时! C++ 思想: RAII ( Resource Acquisition Is Initialization ) 资源获取视为初始化,反之,资源释放视为销毁 C++ 除了用于初始化的构造函数( constructor ) 还包括了用于销毁的解构函数( destructor ) 离开 {} 作用域自动释放 手动释放 RAII :避免犯错误 与 Java :离不开构造函数 • 如题,那么如何定义构造函数呢? BV1h64y197Fd 自定义构造函数:无参数 自定义构造函数:无参数(使用初始化表达式) 为什么需要初始化表达式? 1. 假如类成员为 const 和引用 2. 假如类成员没有无参构造函数 3. 避免重复初始化,更高效 自定义构造函数:多个参数 自定义构造函数:单个参数 自定义构造函数:单个参数(陷阱) 自定义构造函数:单个参数(避免陷阱)0 码力 | 96 页 | 16.28 MB | 1 年前3C++高性能并行编程与优化 - 课件 - 08 CUDA 开启的 GPU 编程
CUDA 编译器。 GCC 编译器相应的私货则 是 __attribute__((“inline”)) 。 • 注意声明为 __inline__ 不一定就保证内联了,如果函数太大编 译器可能会放弃内联化。因此 CUDA 还提供 __forceinline__ 这个关键字来强制一个函数为内联。 GCC 也有相应的 __attribute__((“always_inline”)) 。 • 此外,还有 生成两份源码级不同的 代码。 __CUDA_ARCH__ 是个版本号 • 其实 __CUDA_ARCH__ 是一个整数,表 示当前编译所针对的 GPU 的架构版本号 是多少。这里是 520 表示版本号是 5.2.0 ,最后一位始终是 0 不用管,我们 通常简称他的版本号为 52 就行了。 • 这个版本号是编译时指定的版本,不是运 行时检测到的版本。编译器默认就是最老 的 52 ,能兼容所有 GTX900 CMake 设置架构版本号 • 可以用 CMAKE_CUDA_ARCHITECTURES 这个变量 ,设置要针对哪个架构生成 GPU 指令码。 • 小彭老师的显卡是 RTX2080 ,他的版本号是 75 ,因 此最适合他用的指令码版本是 75 。 • 如果不指定,编译器默认的版本号是 52 ,他是针对 GTX900 系列显卡的。 • 不过英伟达的架构版本都是向前兼容的,即版本号为 750 码力 | 142 页 | 13.52 MB | 1 年前3《深入浅出MFC》2/e
买繁体版之管道。一来我不知道是否台湾出版公司有提供海外邮购或电购,二 来即使有,想必带给大家很大的麻烦,三来两岸消费水平之差异带给大陆读者 的负担,亦令我深感不安。 1. 这个文档是从侯捷网站提供的繁体板简体化过来的。 2. 由于排版问题,有些繁体说法在换行时候没有被替换,所以遇到问题大家可以对照原文比较一下。 3. 附录、无责任书评那个文件没有转(估计看到那个地方的时候,你手里也该有一本纸板的了)。 这些,怎不教我心怀感谢,并且更加戒慎恐惧! 感谢所有读者促成这本书的更精致化。Visual C++ 5.0 面世了,MFC 则停留在4.2,程序设计 的主轴没有什么大改变。对于新读者,本书乃全新产品自不待言,您可以从目录中细细琢磨 所有的主题。对于老读者,本书所带给您的,是更精致的制作,以及数章新增的内容(请看 第0章「与前版本之差异」)。 6 最后,我要说,我知道,这本书真的带给许多人很扎实的东西。而我所以愿意不计代价去做 新竹1997.04.15 jjhou@ccca.nctu.edu.tw FAX 886-3-5733976 7 第一版序 有一种软件名曰version control,用来记录程序开发过程中的各种版本,以应不时之需,可以 随时反省、检查、回复过去努力的轨迹。 遗憾的是人的大脑没有version control 的能力。学习过程的彷徨犹豫、挫折困顿、在日积月 累的渐悟或x那之间的顿悟之后,彷0 码力 | 1009 页 | 11.08 MB | 1 年前3C++高性能并行编程与优化 - 课件 - 11 现代 CMake 进阶指南
不会优化)。 我们稍后会详细捋一遍类似于 CMAKE_BUILD_TYPE 这样的东西。绝 大多数 CMakeLists.txt 开头都会有的部分,可以说是“标准模板”了。 project :初始化项目信息,并把当前 CMakeLists.txt 所在位置作为根 目录 这里初始化了一个名称为 hellocmake 的项目,为什么需要项目名? 对于 MSVC ,他会在 build 里生成 hellocmake 表示当前源码目录的位置,例如 ~/hellocmake 。 CMAKE_CURRENT_BINARY_DIR 表示当前输出目录的位置,例如 ~/hellocmake/build 。 project :初始化项目信息,并把当前 CMakeLists.txt 所在位置作为根 目录 和子模块的关系: PROJECT_x_DIR 和 CMAKE_CURRENT_x_DIR 的 区别 PROJECT_SOURCE_DIR 就会是子模块的源码目录而不是外层了。 这时候 CMake 会认为这个子模块是个独立的项目,会额外做一些初始化。 他的构建目录 PROJECT_BINARY_DIR 也会变成 build/< 源码相对路径 > 。 这样在 MSVC 上也会看见 build/mylib/mylib.vcxproj 的生成。 project 的初始化: LANGUAGES 字段 • project( 项目名 LANGUAGES 使用的语言列表0 码力 | 166 页 | 6.54 MB | 1 年前3C++高性能并行编程与优化 - 课件 - 04 从汇编角度看编译器优化
器处理寄存器翻车( register spill )的压力。 • 因此 64 位比 32 位机器相比,除了内存突破 4GB 限制外,也有一定性能优势。 8 位, 16 位, 32 位, 64 位版本 al, ax, eax, rax r15b, r15w, r15d, r15 AT&T 汇编语言 GCC 编译器所生成的汇编语言就属于这种 返回值:通过 eax 传出 movl $42, %eax 令解码和指令缓存的压力等原因,出现加速超过 4 倍的情况。 第 1 章:化简 编译器优化:代数化简 编译器优化:常量折叠 编译器优化:举个例子 编译器优化:我毕竟不是万能的 结论:尽量避免代码复杂化,避免使用会造 成 new/delete 的容器。 简单的代码,比什么优化手段都强。 造成 new/delete 的容器:我是说,内存分配在堆上的容器 • 存储在堆上(妨碍优化): • vector 编译器优化: call 变 jmp 多个函数定义在同一个文件中 如果 _Z5otheri 定义在同一个文件中,编 译器会直接调用,没有 @PLT 表示未定义 对象。减轻了链接器的负担。 编译器优化:内联化 只有定义在同一个文件的函数可以被内联 !否则编译器看不见函数体里的内容怎么 内联呢? 为了效率我们可以尽量把常用函数定义在 头文件里,然后声明为 static 。这样调用 他们的时候编译器看得到他们的函数体,0 码力 | 108 页 | 9.47 MB | 1 年前3C++高性能并行编程与优化 - 课件 - 12 从计算机组成原理看 C 语言指针
之外的其他类型则没有区别,可以放心使用。 无符号整数: unsigned 修饰 有符号版本 无符号版本 char unsigned char short unsigned short int unsigned int long unsigned long long long unsigned long long 无符号版本的类型不能表示负数,但是他在正数的表达范围更大。 此外,有的教材采用不同的写法,比如: long int 和 unsigned long 等价 unsigned long long int 和 unsigned long long 等价 有符号整数: signed 修饰 有符号版本 无符号版本 signed char unsigned char signed short unsigned short signed int unsigned int signed long unsigned unsigned long long 类型 • 小写也是可以的: • 32ull 也是 unsigned long long 类型 字面常量的特殊规则:如果 int 表示不下,则自动选择较大的类型 标准化的类型: stdint.h • 而实际上,尽管主流操作系统上 int 都是 32 位的, C 语言标准并没有规定 int 就是 32 位 的。 • int 甚至可以是 16 位的!只不过主流操作系统一致认为是0 码力 | 128 页 | 2.95 MB | 1 年前3
共 29 条
- 1
- 2
- 3