一直想尝试自己动手构建一个简单的深度学习训练框架,包括数据读取与处理、PS、NN前后向传播、模型save和load、不同训练方式(offline/online .etc)、指标监控、模型部署等部分, 去深入研究内部深度学习训练框架及horovod、byteps、pslite、tensorflow等框架源码,感觉非常吃力。到底还是C++基础知识太薄弱了,没有系统的去学习过,都是碰到问题了才去查原因,有需求了才去查解决方案,虽然能够搞定手头问题,但是对C++的理解却始终浮于表面,后面将会分两到三篇文章对C++的基础知识点进行梳理,然后结合几个框架,逐步跟大家分享和探讨构建一个全流程的深度学习框架过程中涉及到的一些知识点。
1. 一个C++源文件从文本到可执行文件经历的过程:gcc hello.c -o hello
(一) 预处理阶段:gcc -E hello.c -o hello.i
对源代码文件中文件包含关系(头文件)、预编译语句(宏定义)进行分析和替换,生成预编译文件。
(二) 编译阶段:gcc –S hello.i –o hello.s
将经过预处理后的预编译文件转换成特定汇编代码(编译原理相关,词法分析、语法分析、语义分析等),生成汇编文件
(三) 汇编阶段:gcc –c hello.s –o hello.o
将编译阶段生成的汇编文件转化成机器码,生成可重定位目标文件
(四) 链接阶段:gcc hello.o –o hello
将多个目标文件及所需要的库打包连接成最终的可执行目标文件(或库文件以供其他程序使用)
2. .c .cc .cpp .h .hpp .inl 这些后缀名都有什么区别
- C中:头文件后缀名.h, 源文件后缀名.c
- C++中:头文件后缀名.h, .hpp, .hxx, 源文件后缀名.cpp, .cc, .cxx, .C .c++
- .h和.hpp的区别是:*.h里面只有声明,没有实现,而*.hpp里声明实现都有,后者可以减少.cpp的数量,适合用来编写公用的开源库。
- inl 文件是内联函数的源文件。内联函数通常在c++头文件中实现,但有的时候内联函数较多或者出于一些别的考虑(使头文件看起来更简洁等),往往会将这部分具体定义的代码添加到INL文件中,然后在该头文件的末尾将其用#include引入。由此也可以看到inl文件的一个用法的影子——模板函数、模板类的定义代码的存放。