English | 中文
這是一個展示如何使用 C++ Metaprogramming 技術來實現神經網路編譯器的簡單可執行範例專案。
- 📖 C++ 核心技術 Cheat Sheet - 詳細的 C++ 技術參考
- 📊 Benchmark 比較報告 - 性能比較分析
本專案演示了以下 C++ Metaprogramming 技術在 NN 編譯器中的應用:
- Template Metaprogramming (T-MP): 用於創建型別安全的張量運算
- Expression Templates: 用於優化張量表達式,避免臨時物件
- Constexpr: 用於編譯時計算和優化
- 型別系統: 在編譯時進行形狀檢查和推導
- 編譯時核心生成: 根據張量形狀生成優化的程式碼
nn_meta/
├── CMakeLists.txt # CMake 構建配置
├── README.md # 本文件
├── CXX_CHEATSHEET.md # C++ 核心技術快速參考表
├── benchmark_comparison_report.md # Benchmark 比較報告
├── run_benchmarks.sh # Benchmark 執行腳本
├── include/ # 頭文件目錄
│ ├── tensor.hpp # 張量類別(使用 T-MP)
│ ├── expression_template.hpp # 表達式模板
│ ├── nn_compiler.hpp # NN 編譯器工具
│ └── benchmark.hpp # Benchmark 工具
├── src/
│ ├── main.cpp # 主程式和範例
│ └── benchmark_cpp.cpp # C++ benchmark 程式
└── benchmarks/ # Benchmark 腳本目錄
├── benchmark_pytorch.py # PyTorch benchmark
└── compare_benchmarks.py # 比較報告生成器
- C++20 或更高版本的編譯器(GCC 10+, Clang 10+, MSVC 2019+)
- CMake 3.15 或更高版本
- Python 3.6+(用於 benchmark 比較,可選)
- PyTorch(用於 benchmark 比較,可選)
# 創建構建目錄
mkdir build
cd build
# 配置專案
cmake ..
# 編譯
cmake --build .
# 執行
./NNMetaProgramming或者使用單一命令:
mkdir -p build && cd build && cmake .. && cmake --build . && ./NNMetaProgrammingcd build
cmake --build . --target benchmark_cpp
./benchmark_cpp使用 Template Metaprogramming 創建在編譯時就知道形狀的張量:
Tensor<float, 2, 3> tensor_a{1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f};
// 形狀 [2, 3] 在編譯時確定,型別系統保證型別安全使用表達式模板避免創建臨時物件:
auto expr_result = expr(a) + expr(b);
// 不會創建臨時的張量物件,直接在計算時求值根據張量大小在編譯時選擇最優的實現:
auto result = matmul(mat_a, mat_b);
// 對於小矩陣,使用完全展開的迴圈
// 對於大矩陣,使用運行時迴圈使用 constexpr 在編譯時執行計算:
constexpr std::size_t fact_5 = constexpr_utils::factorial(5);
// 在編譯時計算,零運行時開銷定義在編譯時就知道輸入輸出形狀的層:
LinearLayer<float, 3, 2> layer; // 3 輸入 -> 2 輸出
// 型別系統保證形狀匹配本專案使用了大量現代 C++ 技術,詳細的技術參考請查看:
📖 C++ 核心技術 Cheat Sheet | English
包含以下技術的詳細說明和範例:
- Template Metaprogramming
- Constexpr 與編譯時計算
- Variadic Templates
- Fold Expressions
- if constexpr
- Type Traits
- Expression Templates
- CRTP 模式
- Lambda 表達式
- 以及其他現代 C++ 特性
- 型別安全: 編譯時檢查張量形狀匹配
- 零開銷抽象: 編譯器可以完全優化掉抽象層
- 編譯時優化: 根據形狀生成最優化的程式碼
- 避免臨時物件: 表達式在求值時才計算,不創建中間張量
- 延遲求值: 可以優化整個表達式樹
- 效能提升: 減少記憶體分配和複製
- 編譯時計算: 常數在編譯時計算,零運行時開銷
- 型別推導: 編譯器可以推導出更多資訊進行優化
- 元編程增強: 使模板元編程更強大和易用
本專案包含與主流深度學習框架(PyTorch)的 benchmark 比較功能。
./run_benchmarks.sh這個腳本會:
- 自動構建 C++ benchmark 程式
- 運行 C++ benchmark
- 運行 PyTorch benchmark
- 生成比較報告
# 1. 構建 C++ benchmark
cd build
cmake --build . --target benchmark_cpp
# 2. 運行 C++ benchmark
./benchmark_cpp
# 3. 運行 PyTorch benchmark
cd ../benchmarks
python3 benchmark_pytorch.py
# 4. 生成比較報告(需要手動解析輸出)Benchmark 包含以下運算的比較:
-
矩陣乘法 (MatMul)
- 小矩陣 (4x4)
- 中矩陣 (32x32)
- 大矩陣 (128x128)
-
ReLU 激活函數
- 小張量 (16 元素)
- 中張量 (1024 元素)
- 大張量 (4096 元素)
-
線性層前向傳播
- 小層 (64 -> 32)
- 中層 (256 -> 128)
- 大層 (1024 -> 512)
-
元素級運算
- 張量加法
Benchmark 會輸出以下統計資訊:
- Mean: 平均執行時間(微秒)
- Median: 中位數執行時間(微秒)
- StdDev: 標準差
- Min/Max: 最小/最大執行時間
比較報告會顯示:
- 各框架的執行時間
- 相對速度提升(Speedup)
- 性能分析
- 編譯器優化: C++ benchmark 使用
-O3優化,這可能導致某些小運算被完全優化掉 - PyTorch 版本: 確保安裝了 PyTorch(
pip install torch) - 系統負載: 建議在系統負載較低時運行 benchmark 以獲得準確結果
- CPU vs GPU: PyTorch benchmark 會自動檢測是否使用 GPU,C++ 版本目前僅使用 CPU
這些技術在實際的 NN 編譯器(如 TVM、TensorFlow XLA)中被廣泛使用:
- 高效核心生成: 根據模型層的特定形狀生成高度優化的 CUDA/OpenCL 核心
- 張量運算優化: 使用表達式模板優化複雜的張量運算鏈
- 型別系統: 在編譯時檢查模型的正確性,避免運行時錯誤
- 編譯時優化: 使用 constexpr 和模板特化進行編譯時優化
隨著 C++ 標準的演進,以下功能將進一步增強 NN 編譯器開發:
- Reflection (C++23/26): 允許在編譯時檢查和操作程式碼結構
- Metaclasses (C++26/29): 允許定義類別的創建方式,簡化層定義
- 增強的 Constexpr: 更強大的編譯時計算能力
本專案僅供學習和示範用途。