 面向亿行 C/C++ 代码的静态分析系统设计及实践-肖枭面向亿行C/C++代码的 静态分析系统设计及实践 肖枭 自我介绍 2016年香港科技大学取得博士学位 过去10年一直以极高的热情从事静态 分析技术的学术用研究 合作创办源伞科技,致力于推动静态 分析技术在企业中的应用 目录 代码质量管理是个大问题 静态分析+代码评审的实践  学习和强调,红线和惩罚,100%的测试 覆盖率,和事后复盘并不够  有经验的程序员也会犯错  对代码提要求很难监督落实0 码力 | 39 页 | 6.88 MB | 1 年前3 面向亿行 C/C++ 代码的静态分析系统设计及实践-肖枭面向亿行C/C++代码的 静态分析系统设计及实践 肖枭 自我介绍 2016年香港科技大学取得博士学位 过去10年一直以极高的热情从事静态 分析技术的学术用研究 合作创办源伞科技,致力于推动静态 分析技术在企业中的应用 目录 代码质量管理是个大问题 静态分析+代码评审的实践  学习和强调,红线和惩罚,100%的测试 覆盖率,和事后复盘并不够  有经验的程序员也会犯错  对代码提要求很难监督落实0 码力 | 39 页 | 6.88 MB | 1 年前3
 《深入浅出MFC》2/e则停留在4.2,程序设计 的主轴没有什么大改变。对于新读者,本书乃全新产品自不待言,您可以从目录中细细琢磨 所有的主题。对于老读者,本书所带给您的,是更精致的制作,以及数章新增的内容(请看 第0章「与前版本之差异」)。 6 最后,我要说,我知道,这本书真的带给许多人很扎实的东西。而我所以愿意不计代价去做 些不求近利的深耕工作,除了这是身为专业作家的责任,以及个人的兴趣之外,是的,我自 己是工程师,我最清楚工程师在学习MFC 新竹1997.04.15 jjhou@ccca.nctu.edu.tw FAX 886-3-5733976 7 第一版序 有一种软件名曰version control,用来记录程序开发过程中的各种版本,以应不时之需,可以 随时反省、检查、回复过去努力的轨迹。 遗憾的是人的大脑没有version control 的能力。学习过程的彷徨犹豫、挫折困顿、在日积月 累的渐悟或x那之间的顿悟之后,彷 磁片內容與安裝 / 34 範例程式說明 / 34 與前版本之差異 / 39 如何聯絡作者 / 40 第㆒篇 勿在浮砂築高臺 - 本書技術前提 / 001 第1章 Win32 程式基本觀念/ 003 Win32 程式開發流程/ 005 需要什麼函式庫(.LIB) / 005 需要什麼表頭檔(0 码力 | 1009 页 | 11.08 MB | 1 年前3 《深入浅出MFC》2/e则停留在4.2,程序设计 的主轴没有什么大改变。对于新读者,本书乃全新产品自不待言,您可以从目录中细细琢磨 所有的主题。对于老读者,本书所带给您的,是更精致的制作,以及数章新增的内容(请看 第0章「与前版本之差异」)。 6 最后,我要说,我知道,这本书真的带给许多人很扎实的东西。而我所以愿意不计代价去做 些不求近利的深耕工作,除了这是身为专业作家的责任,以及个人的兴趣之外,是的,我自 己是工程师,我最清楚工程师在学习MFC 新竹1997.04.15 jjhou@ccca.nctu.edu.tw FAX 886-3-5733976 7 第一版序 有一种软件名曰version control,用来记录程序开发过程中的各种版本,以应不时之需,可以 随时反省、检查、回复过去努力的轨迹。 遗憾的是人的大脑没有version control 的能力。学习过程的彷徨犹豫、挫折困顿、在日积月 累的渐悟或x那之间的顿悟之后,彷 磁片內容與安裝 / 34 範例程式說明 / 34 與前版本之差異 / 39 如何聯絡作者 / 40 第㆒篇 勿在浮砂築高臺 - 本書技術前提 / 001 第1章 Win32 程式基本觀念/ 003 Win32 程式開發流程/ 005 需要什麼函式庫(.LIB) / 005 需要什麼表頭檔(0 码力 | 1009 页 | 11.08 MB | 1 年前3
 Hello 算法 1.2.0 繁体中文 C++ 版力”,我會竭盡所能,投入最大的“注意力” 來完成本書的創作。 本人自知學疏才淺,書中內容雖然已經過一段時間的打磨,但一定仍有許多錯誤,懇請各位老師與同學批評 指正。 本書中的程式碼附有可一鍵執行的原始檔,託管於 github.com/krahets/hello‑algo 倉庫。 動畫在 PDF 內的展示效果有限,可訪問 www.hello‑algo.com 網頁版以獲得更佳的閱讀體驗。 推薦語 “如果我當年學資料結構與演算法時有《Hello 演算法》,學起來應該會簡單 10 倍!” ——李沐,亞馬遜資深首席科學家 電腦的出現為世界帶來了巨大的變革,它憑藉高速的運算能力與卓越的可程式化特性,成為執行演算法 與處理資料的理想媒介。無論是電玩遊戲的逼真畫面、自動駕駛的智慧決策,還是 AlphaGo 的精彩棋局、 ChatGPT 的自然互動,這些應用都是演算法在電腦上的精妙演繹。 事實上,在電腦 事實上,在電腦問世之前,演算法和資料結構就已經存在於世界的各個角落。早期的演算法相對簡單,例如 古代的計數方法與工具製作步驟等。隨著文明的進步,演算法逐漸變得更加精細和複雜。從巧奪天工的匠人 技藝、到解放生產力的工業產品、再到宇宙運行的科學規律,幾乎每一件平凡或令人驚嘆的事物背後,都隱 藏著精妙的演算法思想。 同樣,資料結構無處不在:大到社會網絡,小到地鐵路線,許多系統都可以建模為“圖”;大到一個國家,小 到一個家庭,社會的0 码力 | 379 页 | 18.79 MB | 10 月前3 Hello 算法 1.2.0 繁体中文 C++ 版力”,我會竭盡所能,投入最大的“注意力” 來完成本書的創作。 本人自知學疏才淺,書中內容雖然已經過一段時間的打磨,但一定仍有許多錯誤,懇請各位老師與同學批評 指正。 本書中的程式碼附有可一鍵執行的原始檔,託管於 github.com/krahets/hello‑algo 倉庫。 動畫在 PDF 內的展示效果有限,可訪問 www.hello‑algo.com 網頁版以獲得更佳的閱讀體驗。 推薦語 “如果我當年學資料結構與演算法時有《Hello 演算法》,學起來應該會簡單 10 倍!” ——李沐,亞馬遜資深首席科學家 電腦的出現為世界帶來了巨大的變革,它憑藉高速的運算能力與卓越的可程式化特性,成為執行演算法 與處理資料的理想媒介。無論是電玩遊戲的逼真畫面、自動駕駛的智慧決策,還是 AlphaGo 的精彩棋局、 ChatGPT 的自然互動,這些應用都是演算法在電腦上的精妙演繹。 事實上,在電腦 事實上,在電腦問世之前,演算法和資料結構就已經存在於世界的各個角落。早期的演算法相對簡單,例如 古代的計數方法與工具製作步驟等。隨著文明的進步,演算法逐漸變得更加精細和複雜。從巧奪天工的匠人 技藝、到解放生產力的工業產品、再到宇宙運行的科學規律,幾乎每一件平凡或令人驚嘆的事物背後,都隱 藏著精妙的演算法思想。 同樣,資料結構無處不在:大到社會網絡,小到地鐵路線,許多系統都可以建模為“圖”;大到一個國家,小 到一個家庭,社會的0 码力 | 379 页 | 18.79 MB | 10 月前3
 C++高性能并行编程与优化 -  课件 - 15 C++ 系列课:字符与字符串针,如果让首地址指针向前移动 n 位,那就实现删除前 n 个字符的效果,而不用实际修改数组本身(更高效)。 C 语言转义符 • 常见的转义符: • ‘\n’ 换行符:另起一行(光标移到下一行行首) • ‘\r’ 回车符:光标移到行首(覆盖原来的字符) • ‘\t’ 缩进符:光标横坐标对齐到 8 的整数倍 • ‘\b’ 退格符:光标左移,删除上个字符 • ‘\\’ 反斜杠:表示这个是真的 \ ,不是转义符 不等价。 • ‘0’ 相当于他的 ASCII 码 48 。 • 而 ‘ \0’ 就是整数 0 。 C 语言转义符 • 常见的转义符: • ‘\n’ 换行符:另起一行(光标移到下一行行首) • ‘\r’ 回车符:光标移到行首(覆盖原来的字符) • ‘\t’ 缩进符:光标横坐标对齐到 8 的整数倍 • ‘\b’ 退格符:光标左移,删除上个字符 • ‘\\’ 反斜杠:表示这个是真的 \ ,不是转义符 不等价。 • ‘0’ 相当于他的 ASCII 码 48 。 • 而 ‘ \0’ 就是整数 0 。 C 语言转义符 • 常见的转义符: • ‘\n’ 换行符:另起一行(光标移到下一行行首) • ‘\r’ 回车符:光标移到行首(覆盖原来的字符) • ‘\t’ 缩进符:光标横坐标对齐到 8 的整数倍 • ‘\b’ 退格符:光标左移,删除上个字符 • ‘\\’ 反斜杠:表示这个是真的 \ ,不是转义符0 码力 | 162 页 | 40.20 MB | 1 年前3 C++高性能并行编程与优化 -  课件 - 15 C++ 系列课:字符与字符串针,如果让首地址指针向前移动 n 位,那就实现删除前 n 个字符的效果,而不用实际修改数组本身(更高效)。 C 语言转义符 • 常见的转义符: • ‘\n’ 换行符:另起一行(光标移到下一行行首) • ‘\r’ 回车符:光标移到行首(覆盖原来的字符) • ‘\t’ 缩进符:光标横坐标对齐到 8 的整数倍 • ‘\b’ 退格符:光标左移,删除上个字符 • ‘\\’ 反斜杠:表示这个是真的 \ ,不是转义符 不等价。 • ‘0’ 相当于他的 ASCII 码 48 。 • 而 ‘ \0’ 就是整数 0 。 C 语言转义符 • 常见的转义符: • ‘\n’ 换行符:另起一行(光标移到下一行行首) • ‘\r’ 回车符:光标移到行首(覆盖原来的字符) • ‘\t’ 缩进符:光标横坐标对齐到 8 的整数倍 • ‘\b’ 退格符:光标左移,删除上个字符 • ‘\\’ 反斜杠:表示这个是真的 \ ,不是转义符 不等价。 • ‘0’ 相当于他的 ASCII 码 48 。 • 而 ‘ \0’ 就是整数 0 。 C 语言转义符 • 常见的转义符: • ‘\n’ 换行符:另起一行(光标移到下一行行首) • ‘\r’ 回车符:光标移到行首(覆盖原来的字符) • ‘\t’ 缩进符:光标横坐标对齐到 8 的整数倍 • ‘\b’ 退格符:光标左移,删除上个字符 • ‘\\’ 反斜杠:表示这个是真的 \ ,不是转义符0 码力 | 162 页 | 40.20 MB | 1 年前3
 C++高性能并行编程与优化 -  课件 - 11 现代 CMake 进阶指南build 目录 • 切换到 build 目录 • 在 build 目录运行 cmake < 源码目录 > 生成 Makefile • 执行本地的构建系统 make 真正开始构建( 4 进程并 行) • 让本地的构建系统执行安装步骤 • 回到源码目录 现代 CMake 提供了更方便的 -B 和 --build 指令,不同平台,统一命 令! • cmake -B build • cmake 是一个空字符串。 因此这里通过 if (NOT CMAKE_BUILD_TYPE) 判断是否为空,如果空 则自动设为 Release 模式。 大多数 CMakeLists.txt 的开头都会有这样三行,为的是让默认的构建类 型为发布模式(高度优化)而不是默认的调试模式(不会优化)。 我们稍后会详细捋一遍类似于 CMAKE_BUILD_TYPE 这样的东西。绝 大多数 CMakeLists.txt Fortran :老年人的编程语言 • CUDA :英伟达的 CUDA ( 3.8 版本新增) • OBJC :苹果的 Objective-C ( 3.16 版本新增) • OBJCXX :苹果的 Objective-C++ ( 3.16 版本新增) • ISPC :一种因特尔的自动 SIMD 编程语言( 3.18 版本新增) • 如果不指定 LANGUAGES ,默认为 C 和 CXX 。 https://cmake0 码力 | 166 页 | 6.54 MB | 1 年前3 C++高性能并行编程与优化 -  课件 - 11 现代 CMake 进阶指南build 目录 • 切换到 build 目录 • 在 build 目录运行 cmake < 源码目录 > 生成 Makefile • 执行本地的构建系统 make 真正开始构建( 4 进程并 行) • 让本地的构建系统执行安装步骤 • 回到源码目录 现代 CMake 提供了更方便的 -B 和 --build 指令,不同平台,统一命 令! • cmake -B build • cmake 是一个空字符串。 因此这里通过 if (NOT CMAKE_BUILD_TYPE) 判断是否为空,如果空 则自动设为 Release 模式。 大多数 CMakeLists.txt 的开头都会有这样三行,为的是让默认的构建类 型为发布模式(高度优化)而不是默认的调试模式(不会优化)。 我们稍后会详细捋一遍类似于 CMAKE_BUILD_TYPE 这样的东西。绝 大多数 CMakeLists.txt Fortran :老年人的编程语言 • CUDA :英伟达的 CUDA ( 3.8 版本新增) • OBJC :苹果的 Objective-C ( 3.16 版本新增) • OBJCXX :苹果的 Objective-C++ ( 3.16 版本新增) • ISPC :一种因特尔的自动 SIMD 编程语言( 3.18 版本新增) • 如果不指定 LANGUAGES ,默认为 C 和 CXX 。 https://cmake0 码力 | 166 页 | 6.54 MB | 1 年前3
 C++高性能并行编程与优化 -  课件 - 16 现代 CMake 模块化项目管理指南分别在各自的目录下有自己的 CMakeLists.txt 。 二、根项目的 CMakeLists.txt 配置 • 在根项目的 CMakeLists.txt 中,设置了默 认的构建模式,设置了统一的 C++ 版本 等各种选项。然后通过 project 命令初始 化了根项目。 • 随后通过 add_subdirectory 把两个子项 目 pybmain 和 biology 添加进来(顺序 无关紧要),这会调用 Studio 。这样以后你每次构建任 何项目, find_package 都能自动找到这个路径的 Qt5 包了。 • (3) 单项目有效。直接在你自己项目的 CMakeLists.txt 最开头写一行(注意要加引号): • set(Qt5_DIR ”D:/Qt5.12.1/msvc2017/lib/cmake/Qt5”) # 一定要加在最前面! 举例, Linux 系统, Qt5 • 例如我把 ,然后重启终端。这样以后你每次构建任何 项目, find_package 都能自动找到这个路径的 Qt5 包了。 • (3) 单项目有效。直接在你自己项目的 CMakeLists.txt 最开头写一行: • set(Qt5_DIR ”/opt/Qt5.12.1/lib/cmake/Qt5”) # 一定要加在最前面! 三种方案利弊分析 • 单次有效(通过命令行)最安全,小彭老师高度推荐。0 码力 | 56 页 | 6.87 MB | 1 年前3 C++高性能并行编程与优化 -  课件 - 16 现代 CMake 模块化项目管理指南分别在各自的目录下有自己的 CMakeLists.txt 。 二、根项目的 CMakeLists.txt 配置 • 在根项目的 CMakeLists.txt 中,设置了默 认的构建模式,设置了统一的 C++ 版本 等各种选项。然后通过 project 命令初始 化了根项目。 • 随后通过 add_subdirectory 把两个子项 目 pybmain 和 biology 添加进来(顺序 无关紧要),这会调用 Studio 。这样以后你每次构建任 何项目, find_package 都能自动找到这个路径的 Qt5 包了。 • (3) 单项目有效。直接在你自己项目的 CMakeLists.txt 最开头写一行(注意要加引号): • set(Qt5_DIR ”D:/Qt5.12.1/msvc2017/lib/cmake/Qt5”) # 一定要加在最前面! 举例, Linux 系统, Qt5 • 例如我把 ,然后重启终端。这样以后你每次构建任何 项目, find_package 都能自动找到这个路径的 Qt5 包了。 • (3) 单项目有效。直接在你自己项目的 CMakeLists.txt 最开头写一行: • set(Qt5_DIR ”/opt/Qt5.12.1/lib/cmake/Qt5”) # 一定要加在最前面! 三种方案利弊分析 • 单次有效(通过命令行)最安全,小彭老师高度推荐。0 码力 | 56 页 | 6.87 MB | 1 年前3
 C++高性能并行编程与优化 -  课件 - 07 深入浅出访存优化章:内存带宽 cpu-bound 与 memory-bound • 通常来说,并行只能加速计算的部分,不能加速内存读写的部分 。 • 因此,对 fill 这种没有任何计算量,纯粹只有访存的循环体,并 行没有加速效果。称为内存瓶颈( memory-bound )。 • 而 sine 这种内部需要泰勒展开来计算,每次迭代计算量很大的 循环体,并行才有较好的加速效果。称为计算瓶颈( cpu- bound 常见操作所花费的时间 • 图中加法 (add) 和乘法 (mul) 都指的整数。 • 区别是浮点的乘法和加法基本是一样速度。 • L1/2/3 read 和 Main RAM read 的时间指的是 读一个缓存行( 64 字节)所花费的时间。 • 根据计算: 125/64*4≈8 • 即从主内存读取一次 float 花费 8 个 cycle , 符合小彭老师的经验公式。 • “right” 和“ wrong” 架构中每个条目的存储 64 字节的数据,这个条目 又称之为缓存行( cacheline )。 • 当访问 0x0048~0x0050 这 4 个字节时,实际会导致 0x0040~0x0080 的 64 字节数据整个被读取到缓存中。 • 这就是为什么我们喜欢把数据结构的起始地址和大小对齐到 64 字节,为的是不要浪费缓存行的存储空间。 缓存的工作机制:写 • 缓存中存储的数据结构:0 码力 | 147 页 | 18.88 MB | 1 年前3 C++高性能并行编程与优化 -  课件 - 07 深入浅出访存优化章:内存带宽 cpu-bound 与 memory-bound • 通常来说,并行只能加速计算的部分,不能加速内存读写的部分 。 • 因此,对 fill 这种没有任何计算量,纯粹只有访存的循环体,并 行没有加速效果。称为内存瓶颈( memory-bound )。 • 而 sine 这种内部需要泰勒展开来计算,每次迭代计算量很大的 循环体,并行才有较好的加速效果。称为计算瓶颈( cpu- bound 常见操作所花费的时间 • 图中加法 (add) 和乘法 (mul) 都指的整数。 • 区别是浮点的乘法和加法基本是一样速度。 • L1/2/3 read 和 Main RAM read 的时间指的是 读一个缓存行( 64 字节)所花费的时间。 • 根据计算: 125/64*4≈8 • 即从主内存读取一次 float 花费 8 个 cycle , 符合小彭老师的经验公式。 • “right” 和“ wrong” 架构中每个条目的存储 64 字节的数据,这个条目 又称之为缓存行( cacheline )。 • 当访问 0x0048~0x0050 这 4 个字节时,实际会导致 0x0040~0x0080 的 64 字节数据整个被读取到缓存中。 • 这就是为什么我们喜欢把数据结构的起始地址和大小对齐到 64 字节,为的是不要浪费缓存行的存储空间。 缓存的工作机制:写 • 缓存中存储的数据结构:0 码力 | 147 页 | 18.88 MB | 1 年前3
 C++高性能并行编程与优化 -  课件 - 08 CUDA 开启的 GPU 编程生成两份源码级不同的 代码。 __CUDA_ARCH__ 是个版本号 • 其实 __CUDA_ARCH__ 是一个整数,表 示当前编译所针对的 GPU 的架构版本号 是多少。这里是 520 表示版本号是 5.2.0 ,最后一位始终是 0 不用管,我们 通常简称他的版本号为 52 就行了。 • 这个版本号是编译时指定的版本,不是运 行时检测到的版本。编译器默认就是最老 的 52 ,能兼容所有 GTX900 CMake 设置架构版本号 • 可以用 CMAKE_CUDA_ARCHITECTURES 这个变量 ,设置要针对哪个架构生成 GPU 指令码。 • 小彭老师的显卡是 RTX2080 ,他的版本号是 75 ,因 此最适合他用的指令码版本是 75 。 • 如果不指定,编译器默认的版本号是 52 ,他是针对 GTX900 系列显卡的。 • 不过英伟达的架构版本都是向前兼容的,即版本号为 75 的 RTX2080 也可以运行版本号为 52 的指令码,虽然 不够优化,但是至少能用。也就是要求:编译期指定的 版本 ≤ 运行时显卡的版本。 CMAKE_CUDA_ARCHITECTURES 会自动转换成 --gpu-code 等编 译 flag 版本号不要太新了 • 比如这里设置了 RTX3000 系列的架构版 本号 86 ,在 RTX2080 上就运行不出结 果。 • 最坑的是他不会报错!也不输出任何东西0 码力 | 142 页 | 13.52 MB | 1 年前3 C++高性能并行编程与优化 -  课件 - 08 CUDA 开启的 GPU 编程生成两份源码级不同的 代码。 __CUDA_ARCH__ 是个版本号 • 其实 __CUDA_ARCH__ 是一个整数,表 示当前编译所针对的 GPU 的架构版本号 是多少。这里是 520 表示版本号是 5.2.0 ,最后一位始终是 0 不用管,我们 通常简称他的版本号为 52 就行了。 • 这个版本号是编译时指定的版本,不是运 行时检测到的版本。编译器默认就是最老 的 52 ,能兼容所有 GTX900 CMake 设置架构版本号 • 可以用 CMAKE_CUDA_ARCHITECTURES 这个变量 ,设置要针对哪个架构生成 GPU 指令码。 • 小彭老师的显卡是 RTX2080 ,他的版本号是 75 ,因 此最适合他用的指令码版本是 75 。 • 如果不指定,编译器默认的版本号是 52 ,他是针对 GTX900 系列显卡的。 • 不过英伟达的架构版本都是向前兼容的,即版本号为 75 的 RTX2080 也可以运行版本号为 52 的指令码,虽然 不够优化,但是至少能用。也就是要求:编译期指定的 版本 ≤ 运行时显卡的版本。 CMAKE_CUDA_ARCHITECTURES 会自动转换成 --gpu-code 等编 译 flag 版本号不要太新了 • 比如这里设置了 RTX3000 系列的架构版 本号 86 ,在 RTX2080 上就运行不出结 果。 • 最坑的是他不会报错!也不输出任何东西0 码力 | 142 页 | 13.52 MB | 1 年前3
 现代C++ 教程:高速上手C++11/14/17/20的内容可能过期,请检查本书网站以及 GitHub 仓库以获取最新内容。 版权声明 本书系欧长坤著,采用“知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议 (CC BY-NC-ND)”进 行许可。https://creativecommons.org/licenses/by-nc-nd/4.0/ 1 目录 目录 目录 序言 7 引言 . . . . . . . . . . . len_foo() 在运行期实际上是返 回一个常数,这也就导致了非法的产生。 注意,现在大部分编译器其实都带有自身编译优化,很多非法行为在编译器优化的加持下会 变得合法,若需重现编译报错的现象需要使用老版本的编译器。 C++11 提供了 constexpr 让用户显式的声明函数或对象构造函数在编译期会成为常量表达式,这 个关键字明确的告诉编译器应该去验证 len_foo 在编译期就应该是一个常量表达式。 == 1) return 1; if(n == 2) return 1; return fibonacci(n-1) + fibonacci(n-2); } 为此,我们可以写出下面这类简化的版本来使得函数从 C++11 开始即可用: constexpr int fibonacci(const int n) { return n == 1 || n == 2 ? 1 : fibonacci(n-1)0 码力 | 83 页 | 2.42 MB | 1 年前3 现代C++ 教程:高速上手C++11/14/17/20的内容可能过期,请检查本书网站以及 GitHub 仓库以获取最新内容。 版权声明 本书系欧长坤著,采用“知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议 (CC BY-NC-ND)”进 行许可。https://creativecommons.org/licenses/by-nc-nd/4.0/ 1 目录 目录 目录 序言 7 引言 . . . . . . . . . . . len_foo() 在运行期实际上是返 回一个常数,这也就导致了非法的产生。 注意,现在大部分编译器其实都带有自身编译优化,很多非法行为在编译器优化的加持下会 变得合法,若需重现编译报错的现象需要使用老版本的编译器。 C++11 提供了 constexpr 让用户显式的声明函数或对象构造函数在编译期会成为常量表达式,这 个关键字明确的告诉编译器应该去验证 len_foo 在编译期就应该是一个常量表达式。 == 1) return 1; if(n == 2) return 1; return fibonacci(n-1) + fibonacci(n-2); } 为此,我们可以写出下面这类简化的版本来使得函数从 C++11 开始即可用: constexpr int fibonacci(const int n) { return n == 1 || n == 2 ? 1 : fibonacci(n-1)0 码力 | 83 页 | 2.42 MB | 1 年前3
 C++高性能并行编程与优化 -  课件 - 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 有所谓的“老师”就不肯动动手敲几行命令(写 doc 文件倒挺勤的),在那里传播假知识。 • 在线做编译器实验推荐这个网站: https://godbolt.org/ • 可以实时看源代码编译的结果,还能选不同的编译器版本和 flag 。 • 不要脑内模拟!你误以为某更改对性能有帮助,然而实际测一下时间有一定可能反而变慢 。 第 3 章:指针 编译器傻了吗? 为什么编译器不优化掉 *c = *a ? 指针别名现象( 指针的差是否超过 1024 来判断是否有重叠现 象。 1. 如果没有重叠,则跳转到 SIMD 版本高效运行。 2. 如果重叠,则跳转到标量版本低效运行,但至少不会错。 SIMD 版 标量版 循环中的矢量化:解决指针别名 所以,让我们加上 __restrict 关键字,打消编译器的顾虑! 这下只需要生成一个 SIMD 版本了,没有了运行时判断重叠的焦虑。 SIMD 版 循环中的矢量化: OpenMP0 码力 | 108 页 | 9.47 MB | 1 年前3 C++高性能并行编程与优化 -  课件 - 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 有所谓的“老师”就不肯动动手敲几行命令(写 doc 文件倒挺勤的),在那里传播假知识。 • 在线做编译器实验推荐这个网站: https://godbolt.org/ • 可以实时看源代码编译的结果,还能选不同的编译器版本和 flag 。 • 不要脑内模拟!你误以为某更改对性能有帮助,然而实际测一下时间有一定可能反而变慢 。 第 3 章:指针 编译器傻了吗? 为什么编译器不优化掉 *c = *a ? 指针别名现象( 指针的差是否超过 1024 来判断是否有重叠现 象。 1. 如果没有重叠,则跳转到 SIMD 版本高效运行。 2. 如果重叠,则跳转到标量版本低效运行,但至少不会错。 SIMD 版 标量版 循环中的矢量化:解决指针别名 所以,让我们加上 __restrict 关键字,打消编译器的顾虑! 这下只需要生成一个 SIMD 版本了,没有了运行时判断重叠的焦虑。 SIMD 版 循环中的矢量化: OpenMP0 码力 | 108 页 | 9.47 MB | 1 年前3
共 28 条
- 1
- 2
- 3













