《深入浅出MFC》2/ecn> Microsoft Developer Studio 与MFC(Microsoft Foundation Classes)相配合,构成了一个强大 的利用C++ 进行32 位Windows 程序开发的工具,但是由于MFC 系统相当庞大,内 容繁杂,并且夹杂着大量令初学者莫明其妙的macros,更加大了学习上的难度。 当今市面上有不少讲解C++ 和VC++ 程序设计的书籍,但C++ 书籍单纯只讲C++,从 印尼、香港、中国大陆、美 国...),也是另一种安慰。在BBS 及Internet News 看到各界对此书的评介,以及对此书内容 的探讨,亦让我感到十分欣喜。 3 这本书(第二版)所使用的开发环境是Visual C++ 5.0 & MFC 4.21。就在第五刷即将印行的 今天,Visual C++ 6.0 也已问世;其中的programming 关键,也就是MFC,在主干上没有什 么变化,因此我不打算为了Visual 侯俊杰台湾.新竹1997.04.15 jjhou@ccca.nctu.edu.tw FAX 886-3-5733976 7 第一版序 有一种软件名曰version control,用来记录程序开发过程中的各种版本,以应不时之需,可以 随时反省、检查、回复过去努力的轨迹。 遗憾的是人的大脑没有version control 的能力。学习过程的彷徨犹豫、挫折困顿、在日积月 累的渐悟或x那之0 码力 | 1009 页 | 11.08 MB | 1 年前3
现代C++ 教程:高速上手C++11/14/17/20平台支持;std::regex 提供了完整的正则表达式支持等等。C++98 已经被实践证明了是一种非常成功 的『范型』,而现代 C++ 的出现,则进一步推动这种范型,让 C++ 成为系统程序设计和库开发更好的 语言。Concept 提供了对模板参数编译期的检查,进一步增强了语言整体的可用性。 总而言之,我们作为 C++ 的拥护与实践者,始终保持接纳新事物的开放心态,才能更快的推进 C++ 的 在传统 C 和 C++ 中,参数的类型都必须明确定义,这其实对我们快速进行编码没有任何帮助,尤 其是当我们面对一大堆复杂的模板类型时,必须明确的指出变量的类型才能进行后续的编码,这不仅拖 慢我们的开发效率,也让代码变得又臭又长。 C++11 引入了 auto 和 decltype 这两个关键字实现了类型推导,让编译器来操心变量的类型。这 使得 C++ 也具有了和其他现代编程语言一样,某种意义上提供了无需操心变量类型的使用习惯。 语言的一部分,这里仅做简单的介绍。 正则表达式描述了一种字符串匹配的模式。一般使用正则表达式主要是实现下面三个需求: 1. 检查一个串是否包含某种形式的子串; 2. 将匹配的子串替换; 3. 从某个串中取出符合条件的子串。 正则表达式是由普通字符(例如 a 到 z)以及特殊字符组成的文字模式。模式描述在搜索文本时要 匹配的一个或多个字符串。正则表达式作为一个模板,将某个字符模式与所搜索的字符串进行匹配。 57 60 码力 | 83 页 | 2.42 MB | 1 年前3
C++高性能并行编程与优化 - 课件 - 06 TBB 开启的并行编程之旅https://github.com/parallel101/course 高性能并行编程与优化 - 课程大纲 • 分为前半段和后半段,前半段主要介绍现代 C++ ,后半段主要介绍并行编程与优化。 1.课程安排与开发环境搭建: cmake 与 git 入门 2.现代 C++ 入门:常用 STL 容器, RAII 内存管理 3.现代 C++ 进阶:模板元编程与函数式编程 4.编译器如何自动优化:从汇编角度看 ,工作复杂度为 O(n) ,其中 n 是元素个数 改进的并行缩并( GPU ) • 刚才那种方式对 c 比较大的情况不友好, 最后一个串行的 for 还是会消耗很多时间 。 • 因此可以用递归的模式,每次只使数据缩 小一半,这样基本每次都可以看做并行的 for ,只需 log2(n) 次并行 for 即可完成 缩并。 • 这种常用于核心数量很多,比如 GPU 上 的缩并。 结论:改进后的并行缩并的时间复杂度为 结束都需要同步,一定程度上妨碍了 CPU 发挥性能;而 且每个 step 后依然写回了数组,数据缓存没法充分利用 。 另辟蹊径:流水线并行 加速比: 6.73 倍 反直觉的并行方式,但是加速效果却很理想,为什么? 流水线模式下每个线程都只做自己的那个步骤( filter ),从 而对指令缓存更友好。且一个核心处理完的数据很快会被另一 个核心用上,对三级缓存比较友好,也节省内存。 且 TBB 的流水线,其实比教科书上描述的传统流水线并行更加优化:0 码力 | 116 页 | 15.85 MB | 1 年前3
C++高性能并行编程与优化 - 课件 - 02 现代 C++ 入门:RAII 内存管理https://github.com/parallel101/course 高性能并行编程与优化 - 课程大纲 • 分为前半段和后半段,前半段主要介绍现代 C++ ,后半段主要介绍并行编程与优化。 1.课程安排与开发环境搭建: cmake 与 git 入门 2.现代 C++ 入门:常用 STL 容器, RAII 内存管理 3.现代 C++ 进阶:模板元编程与函数式编程 4.编译器如何自动优化:从汇编角度看 ](https://github.com/jiayaozhang/OpenVDB_and_TBB) - [C++ 官方文档 ](https://en.cppreference.com/w/) - [C++ 核心开发规范 ](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md) - [LearnCpp 中文版 这样就可以在编译期提前发现错误: 解决方案:要么定义 • 如果需要允许用户拷贝你的 Vector 类对象 ,我们还是需要实现一下的。 • 发现了吗?其实不管是 size/resize 这样的 get/set 模式也好;自定义的拷贝构造函数 也好; RAII 保证异常安全也好;都是在为 面向对象思想的“封装:不变性”服务。 • 即:保证任何单个操作前后,对象都是处于 正确的状态,从而避免程序读到错误数据0 码力 | 96 页 | 16.28 MB | 1 年前3
C++高性能并行编程与优化 - 课件 - 03 现代 C++ 进阶:模板元编程https://github.com/parallel101/course 高性能并行编程与优化 - 课程大纲 • 分为前半段和后半段,前半段主要介绍现代 C++ ,后半段主要介绍并行编程与优化。 1.课程安排与开发环境搭建: cmake 与 git 入门 2.现代 C++ 入门:常用 STL 容器, RAII 内存管理 3.现代 C++ 进阶:模板元编程与函数式编程 4.编译器如何自动优化:从汇编角度看 • 但是却没有出错,这是因为模板没有被调用,所以不会被实际编译! • 而只有当 main 调用了这个函数,才会被编译,才会报错! • 用一个假模板实现延迟编译的技术,可以加快编译的速度,用于代理模式等。 模板函数:一个例子 • 比如,要打印任意一个 vector : 模板函数:配合运算符重载 • 实现用 std::cout << a 打印任意 vector : 模板函数:大家学废了吗! const & ) • 同理, auto const & 可以定义常引用: 自动类型推导:函数返回引用 • 当然,函数的返回类型也可以是 auto & 或者 auto const & 。比如懒汉单例模式: 理解右值:即将消失的,不长时间存在于内存中的值 • 引用又称为左值( l-value )。左值通常对应着一个长时间存在于内 存中的变量。 • 除了左值之外,还有右值( r-value )。右值通常是一个表达式,代0 码力 | 82 页 | 12.15 MB | 1 年前3
C++高性能并行编程与优化 - 课件 - 05 C++11 开始的多线程编程https://github.com/parallel101/course 高性能并行编程与优化 - 课程大纲 • 分为前半段和后半段,前半段主要介绍现代 C++ ,后半段主要介绍并行编程与优化。 1.课程安排与开发环境搭建: cmake 与 git 入门 2.现代 C++ 入门:常用 STL 容器, RAII 内存管理 3.现代 C++ 进阶:模板元编程与函数式编程 4.编译器如何自动优化:从汇编角度看 • shared_lock 同样支持 defer_lock 做参数 , owns_lock() 判断等,同学们自己研究 。 只需一次性上锁,且符合 RAII 思想:访问者模式 Accessor 或者说 Viewer 模式,王鑫磊常用于设计 GPU 容器 OpenVDB 数据结构的访问,也是采用了 Accessor 的设计…… 并且还有 ConstAccessor 和 Accessor 两种,分别对应于读和 线程被唤醒时,只有一个能够被启动。如 果不需要,在 wait() 返回后调用 lck.unlock() 即可。 • 顺便一提, wait() 的过程中会暂时 unlock() 这个锁。 案例:实现生产者 - 消费者模式 • 类似于消息队列…… • 生产者:厨师,往 foods 队列里推送食品 ,推送后会通知消费者来用餐。 • 消费者:等待 foods 队列里有食品,没有 食品则陷入等待,直到被通知。 条件变量:将0 码力 | 79 页 | 14.11 MB | 1 年前3
C++高性能并行编程与优化 - 课件 - 16 现代 CMake 模块化项目管理指南,他们 分别在各自的目录下有自己的 CMakeLists.txt 。 二、根项目的 CMakeLists.txt 配置 • 在根项目的 CMakeLists.txt 中,设置了默 认的构建模式,设置了统一的 C++ 版本 等各种选项。然后通过 project 命令初始 化了根项目。 • 随后通过 add_subdirectory 把两个子项 目 pybmain 和 biology Qt5Config.cmake 文件包含所有相关信息(类似于 nodejs 的 package.json ),比你单独的一个个去找动态库文件要灵活的多。 • 包配置文件由第三方库的作者( Qt 的开发团队)提供,在这个库安装时( Qt 的安装程序 或 apt install 等)会自动放到 /usr/lib/cmake/XXX/XXXConfig.cmake 这个路径(其中 XXX 是包名),供 IMPORTED Targets 章节是在介绍现代 的用法,而 Result Variables 章节是在介绍 古代的用法,我们尽量用现代的那种就行。 官方文档: find_package 的两种模式 指定使用哪种模式 • find_package(TBB MODULE REQUIRED) • 只会寻找 FindTBB.cmake ,搜索路径: 1. ${CMAKE_MODULE_PATH} (默认为0 码力 | 56 页 | 6.87 MB | 1 年前3
C++高性能并行编程与优化 - 课件 - 04 从汇编角度看编译器优化https://github.com/parallel101/course 高性能并行编程与优化 - 课程大纲 • 分为前半段和后半段,前半段主要介绍现代 C++ ,后半段主要介绍并行编程与优化。 1.课程安排与开发环境搭建: cmake 与 git 入门 2.现代 C++ 入门:常用 STL 容器, RAII 内存管理 3.现代 C++ 进阶:模板元编程与函数式编程 4.编译器如何自动优化:从汇编角度看 for 循环内可能的指针别名现象 。 • 不同的编译器这个 pragma 指令不同,这里只 是拿 GCC 举例,其他编译器请自行查找资料 。 循环中的 if 语句:挪到外面来 乘法模式 加法模式 这个案例中,作者的用意很明显,在 is_mul 为真时 执行 a *= b ,否则执行 a += b 。 然而有 if 分支的循环体是难以 SIMD 矢量化的。 循环中的 if 语句:挪到外面来(续)0 码力 | 108 页 | 9.47 MB | 1 年前3
Hello 算法 1.1.0 C++ 版感谢校铨在知识产权方面提供的专业帮助,这对本开源书的完善起到了重要作用; ‧ 感谢苏潼为本书设计了精美的封面和 logo ,并在我的强迫症的驱使下多次耐心修改; ‧ 感谢 @squidfunk 提供的排版建议,以及他开发的开源文档主题 Material‑for‑MkDocs 。 在写作过程中,我阅读了许多关于数据结构与算法的教材和文章。这些作品为本书提供了优秀的范本,确保 了本书内容的准确性与品质。在此感谢所有老师和前辈的杰出贡献! 载机制。 ‧ 缓存行:缓存不是单个字节地存储与加载数据,而是以缓存行为单位。相比于单个字节的传输,缓存行 的传输形式更加高效。 ‧ 预取机制:处理器会尝试预测数据访问模式(例如顺序访问、固定步长跳跃访问等),并根据特定模式 将数据加载至缓存之中,从而提升命中率。 ‧ 空间局部性:如果一个数据被访问,那么它附近的数据可能近期也会被访问。因此,缓存在加载某一数 据时,也会加载其附近的数据,以提高命中率。 占用空间:链表元素比数组元素占用空间更多,导致缓存中容纳的有效数据量更少。 ‧ 缓存行:链表数据分散在内存各处,而缓存是“按行加载”的,因此加载到无效数据的比例更高。 ‧ 预取机制:数组比链表的数据访问模式更具“可预测性”,即系统更容易猜出即将被加载的数据。 ‧ 空间局部性:数组被存储在集中的内存空间中,因此被加载数据附近的数据更有可能即将被访问。 总体而言,数组具有更高的缓存命中率,因此它在操作0 码力 | 379 页 | 18.47 MB | 1 年前3
Hello 算法 1.0.0 C++版感谢校铨在知识产权方面提供的专业帮助,这对本开源书的完善起到了重要作用; ‧ 感谢苏潼为本书设计了精美的封面和 logo ,并在我的强迫症的驱使下多次耐心修改; ‧ 感谢 @squidfunk 提供的排版建议,以及他开发的开源文档主题 Material‑for‑MkDocs 。 在写作过程中,我阅读了许多关于数据结构与算法的教材和文章。这些作品为本书提供了优秀的范本,确保 了本书内容的准确性与品质。在此感谢所有老师和前辈的杰出贡献! 载机制。 ‧ 缓存行:缓存不是单个字节地存储与加载数据,而是以缓存行为单位。相比于单个字节的传输,缓存行 的传输形式更加高效。 ‧ 预取机制:处理器会尝试预测数据访问模式(例如顺序访问、固定步长跳跃访问等),并根据特定模式 将数据加载至缓存之中,从而提升命中率。 ‧ 空间局部性:如果一个数据被访问,那么它附近的数据可能近期也会被访问。因此,缓存在加载某一数 据时,也会加载其附近的数据,以提高命中率。 占用空间:链表元素比数组元素占用空间更多,导致缓存中容纳的有效数据量更少。 ‧ 缓存行:链表数据分散在内存各处,而缓存是“按行加载”的,因此加载到无效数据的比例更高。 ‧ 预取机制:数组比链表的数据访问模式更具“可预测性”,即系统更容易猜出即将被加载的数据。 ‧ 空间局部性:数组被存储在集中的内存空间中,因此被加载数据附近的数据更有可能即将被访问。 总体而言,数组具有更高的缓存命中率,因此它在操作0 码力 | 378 页 | 17.59 MB | 1 年前3
共 25 条
- 1
- 2
- 3













