NativeScript 101with native code • React Support • API Access via Native Modules • UI Thread vs JS Thread • Angular/Vue/Vanilla vs React • Progress vs Facebook • Apache 2.0 vs BSD+ JavaScript-Driven Native • Share Code Behind o Vanilla JavaScript o Built-in MVVM Pattern o Angular Support o TypeScript Support o Vue Support (Community-Driven) o Preact Support (Community-Driven) Debugging Strategies o Debug by alert0 码力 | 90 页 | 40.11 MB | 1 年前3
C++高性能并行编程与优化 - 课件 - 02 现代 C++ 入门:RAII 内存管理,后半段主要介绍并行编程与优化。 1.课程安排与开发环境搭建: cmake 与 git 入门 2.现代 C++ 入门:常用 STL 容器, RAII 内存管理 3.现代 C++ 进阶:模板元编程与函数式编程 4.编译器如何自动优化:从汇编角度看 C++ 5.C++11 起的多线程编程:从 mutex 到无锁并行 6.并行编程常用框架: OpenMP 与 Intel TBB 7.被忽视的访存优化:内存带宽与 zhihu.com/p/350068132 未来: C++20 引入模块( module ) https://zhuanlan.zhihu.com/p/350136757 未来: C++20 允许函数参数为自动推断( auto ) 未来: C++20 引入协程( coroutine )和生成器( generator ) 未来: C++20 标准库加入 format 支持 跑远了! • 鉴于 这种情况出现时,就意味着你需要把成员变量的读写封装为成员函数 不变性:请勿滥用封装 • 仅当出现“修改一个成员时,其他也成员要 被修改,否则出错”的现象时,才需要 getter/setter 封装。 • 各个成员之间相互正交,比如数学矢量类 Vec3 ,就没必要去搞封装,只会让程序员 变得痛苦,同时还有一定性能损失:特别 是如果 getter/setter 函数分离了声明和定 义,实现在另一个文件时!0 码力 | 96 页 | 16.28 MB | 1 年前3
C++高性能并行编程与优化 - 课件 - Zeno 中的现代 C++ 最佳实践 INode 一切节点的公共基类。 多态的经典案例 • IObject 具有一个 eatFood 纯虚函数,而 CatObject 和 DogObject 继承自 IObject ,他 们实现了 eatFood 这个虚函数,实现了多态。 • 注意这里解构函数( ~IObject )也需要是虚函数 ,否则以 IObject * 存储的指针在 delete 时只 会释放 IObject 里的成员,而不会释放 m_catFood 。所以 这里的解构函数也是多态的,他根据类型的不同 调用不同派生类的解构函数。 多态用于设计模式之“模板模式” • 这样之后如果有一个任务是要基于 eatFood 做文章,比如要重复 eatFood 两遍。 • 就可以封装到一个函数 eatTwice 里,这个函数只需接受他们共同的基类 IObject 作为参数,然后调 用 eatFood 这个虚函数来做事(而不是直接操作具体的猫和狗本身)。 dont-repeat-yourself ), 也让函数的作者不必去关注点从猫和狗的其他具体细节,只需把握住他们统一具有的“吃”这个接口。 小知识: shared_ptr 如何深拷贝? 浅拷贝: 深拷贝: 思考:能不能把拷贝构造函数也作为虚函数? • 现在我们的需求有变,不是去对同一个对象调用两次 eatTwice ,而是先把对象复制一份 拷贝,然后对对象本身和他的拷贝都调用一次 eatFood 虚函数。 • 代码如下0 码力 | 54 页 | 3.94 MB | 1 年前3
C++高性能并行编程与优化 - 课件 - 03 现代 C++ 进阶:模板元编程,后半段主要介绍并行编程与优化。 1.课程安排与开发环境搭建: cmake 与 git 入门 2.现代 C++ 入门:常用 STL 容器, RAII 内存管理 3.现代 C++ 进阶:模板元编程与函数式编程 4.编译器如何自动优化:从汇编角度看 C++ 5.C++11 起的多线程编程:从 mutex 到无锁并行 6.并行编程常用框架: OpenMP 与 Intel TBB 7.被忽视的访存优化:内存带宽与 GPU 专题) 为什么需要模板函数( template ) • 避免重复写代码。 • 比如,利用重载实现“将一个数乘以 2” 这个 功能,需要: 为什么面向对象在 HPC 不如函数式和元编程香了? 这个例子要是按传统的面向对象思想,可能是这样: 令 Int, Float, Double 继承 Numeric 接口类并实现 ,其中 multiply(int) 作为虚函数。然后定义: Numeric 几个,然后每个运算符都要声明一个纯虚函数吗? 而且, Float 的乘法应该是 multiply(float) ,你也去 定义好几个重载吗?定义为 multiply(Numeric *) 的话 依然会违背你们的开 - 闭原则:比如 3.14f * 3 ,两 端是不同的类型,怎么处理所有可能类型的排列组合 ? 不如放弃类和方法的概念,欣然接受全局函数和重载 。 模板函数:定义 • 使用 template0 码力 | 82 页 | 12.15 MB | 1 年前3
C++高性能并行编程与优化 - 课件 - 08 CUDA 开启的 GPU 编程https://github.com/parallel101/course 前置条件 • 学过 C/C++ 语言编程。 • 理解 malloc/free 之类的概念。 • 熟悉 STL 中的容器、函数模板等。 • 英伟达 GTX900 及以上显卡。 • CUDA 11 及以上。 • CMake 3.18 及以上。 我负责监督你学习 第 0 章: Hello, world! CMake • 定义函数 kernel ,前面加上 __global__ 修 饰符,即可让他在 GPU 上执行。 • 不过调用 kernel 时,不能直接 kernel() ,而 是要用 kernel<<<1, 1>>>() 这样的三重尖括 号语法。为什么?这里面的两个 1 有什么用 ?稍后会说明。 • 运行以后,就会在 GPU 上执行 printf 了。 • 这里的 kernel 函数在 GPU GPU 上执行,称为核 函数,用 __global__ 修饰的就是核函数。 没有反应?同步一下! • 然而如果直接编译运行刚刚那段代码,是不会打印出 Hello, world! 的。 • 这是因为 GPU 和 CPU 之间的通信,为了高效,是异 步的。也就是 CPU 调用 kernel<<<1, 1>>>() 后,并不 会立即在 GPU 上执行完毕,再返回。实际上只是把 kernel0 码力 | 142 页 | 13.52 MB | 1 年前3
C++高性能并行编程与优化 - 课件 - 13 C++ STL 容器全解之 vector标准库五大件:迭代器( iterator ) C++ 标准库五大件:算法( algorithm ) C++ 标准库五大件:仿函数( functor ) C++ 标准库五大件:分配器( allocator ) 侯捷 STL 侯捷 STL vector 容器 vector 容器:构造函数 • vector 的功能是长度可变的数组,他里面的数据 存储在堆上。 • vector 是一个模板类,第一个模板参数是数组里 是一个模板类,第一个模板参数是数组里 元素的类型。 • 例如,声明一个元素是 int 类型的动态数组 a : • vectora; vector 容器:构造函数和 size • vector 可以在构造时指定初始长度。 • explicit vector(size_t n); • 例如,要创建一个长度为 4 的 int 型数组 : • vector a(4); • 之后可以通过 const &operator[](size_t i) const noexcept; vector 容器: at • 为了防止不小心越界,可以用 a.at(i) 替代 a[i] , at 函数会检测索引 i 是否越界,如果他 发现索引 i >= a.size() 则会抛出异常 std::out_of_range 让程序提前终止(或者被 try-catch 捕获),配合任意一款调试器,就可 0 码力 | 90 页 | 4.93 MB | 1 年前3
C++高性能并行编程与优化 - 课件 - 15 C++ 系列课:字符与字符串实际上会被编译器翻译成他对应的 ASCII 码: 97 。写 ‘ a’ 和写 (char)97 是完全一样的,方便阅读的语法糖而已。 “char 即整数”思想应用举例 “char 即整数”思想应用举例 C 语言帮手函数 帮手函数大全 • isupper(c) 判断是否为大写字母(‘ A’ <= c && c <= ‘Z’ )。 • islower(c) 判断是否为小写字母(‘ a’ <= c && c <= ‘z’ <= 31 或 c == 127 )。 • toupper(c) 把小写字母转换为大写字母,如果不是则原封不动返回。 • tolower(c) 把大写字母转换为小写字母,如果不是则原封不动返回。 帮手函数大全 http://c.biancheng.net/ref/ctype_h/ 关于 char 类型的一个冷知识 • C 语言其实只规定了 unsigned char 是无符号 8 位整数, signed 。 • hello 每个字符都连续地排列在这个数组中,那么末尾的 0 是怎么回事?原来 C 语言的字符串因为只保留数组的 首地址指针(指向第一个字符的指针),在以 char * 类型 传递给其他函数时,其数组的长度无法知晓。为了确切知 道数组在什么地方结束,规定用 ASCII 码中的“空字符”也 就是 0 来表示数组的结尾。这样只需要一个首地址指针就 能表示一个动态长度的数组,高,实在是高。0 码力 | 162 页 | 40.20 MB | 1 年前3
C++高性能并行编程与优化 - 课件 - 12 从计算机组成原理看 C 语言指针的但是大小相等,则结果是 unsigned 的。 • unsigned int + int = unsigned int • 只有两边都是有符号的 int 时,结果才是有符号的 int 。 浮点与标准库数学函数 浮点数的二进制表示 • float 由 4 个字节组成,也就是 32 个位。 • 最高位是符号位,接着的 8 位是指数位 (e) 。 • 剩下的 23 位是底数位 (m) 。 • 值得注意的是指数位 ,作为牛顿 迭代的初始猜测值而已。看他的 i >> 1 这 里,就是把指数和底数都移动了 1 (因为 符号始终是无符号,底数影响不大)。 abs 函数:取出绝对值 • 可以用 abs 这个函数取出一个整数的绝对值 。 abs 函数:取出绝对值 • 如果用来获取 float 类型的绝对值呢? • 编译通过了,但是结果却不对! • 你会发现 x 无论如何变化,都是 0.0 。 • 左右)。 abs 函数:取出绝对值 • 而刚刚的例子中我们的 abs 返回类型其实始 终是 int ,被送到 printf 里却以 “ %f” 的方式 去读出,所以出错了。 • 因此我们先把 abs 的返回值写入到一个 float 类型变量里试试看,果然有了变化。 • 但还是不对,按理说 abs(-3.14) 应该是 3.14 的,怎么会变成 3.00 呢? abs 函数:取出整数的绝对值0 码力 | 128 页 | 2.95 MB | 1 年前3
C++高性能并行编程与优化 - 课件 - 05 C++11 开始的多线程编程,后半段主要介绍并行编程与优化。 1.课程安排与开发环境搭建: cmake 与 git 入门 2.现代 C++ 入门:常用 STL 容器, RAII 内存管理 3.现代 C++ 进阶:模板元编程与函数式编程 4.编译器如何自动优化:从汇编角度看 C++ 5.C++11 起的多线程编程:从 mutex 到无锁并行 6.并行编程常用框架: OpenMP 与 Intel TBB 7.被忽视的访存优化:内存带宽与 现代 C++ 中的多线程: std::thread • C++11 开始,为多线程提供了语言级别的 支持。他用 std::thread 这个类来表示线 程。 • std::thread 构造函数的参数可以是任意 lambda 表达式。 • 当那个线程启动时,就会执行这个 lambda 里的内容。 • 这样就可以一边和用户交互,一边在另一 个线程里慢吞吞下载文件了。 错误:找不到符号 类的成员函数 join() 来等待该进程结束。 std::thread 的解构函数会销毁线程 • 作为一个 C++ 类, std::thread 同样遵循 RAII 思想和三五法则:因为管理着资源, 他自定义了解构函数,删除了拷贝构造 / 赋 值函数,但是提供了移动构造 / 赋值函数。 • 因此,当 t1 所在的函数退出时,就会调用 std::thread 的解构函数,这会销毁0 码力 | 79 页 | 14.11 MB | 1 年前3
C++高性能并行编程与优化 - 课件 - 性能优化之无分支编程 Branchless Programming以上时,对于只有两个分支的 if- else ,编译器往往会自动检测到可以优化,帮你应用 “妙用加减乘”了,无法体现手动优化的意义。 • 注:此处采用函数指针不仅是为了重用代码,也可以 避免 clamp 被编译器自动内联到 test 函数体内。 • 微软编译器的同学,要把 __attribute__((noinline)) 换成 __declspec(noinline) 才能编译。 不同写法的性能测试 EDOM ,产生副作用。而原先的三目运算 符 ?: 由于具有“短路”特性,当 x < 0 时第一个分支 sqrt(x) 不会执行,没有副作用。不一 样了! • 总之,对于这种有副作用的函数,或是有可能返回 NaN 的函数,无法“妙用加减乘”优化 。 冷静分析,学会变通 • return x >= 0 ? sqrt(x) : 0; • 但是我们可以变通一下,既然从返回值优化不行,从参数入手怎样?首先已知 不得不分支时可以采取的优化手段: likely 和 unlikely 除了 if-else 分支之外:函数指针也是一种分支,也有预判的开销 • 函数调用相当于无条件跳转指令: jmp label 或者说 call label 。 • if-else 对应于条件跳转指令: je label , jne label , jb label 等。 • 而函数指针也是无条件跳转指令: jmp [pointer] 或者说 call [pointer]0 码力 | 47 页 | 8.45 MB | 1 年前3
共 25 条
- 1
- 2
- 3













