以下是针对 Windows 系统 使用 oneDNN、oneMKL、oneTBB 的详细指南,包括安装、配置和示例代码编译方法:
一、安装与配置
1. oneDNN
-
安装方法
- 下载预编译库
从 GitHub 的 oneDNN Release 下载 Windows 预编译包(如onednn-<version>.win.zip
)。 - 源码编译(可选)
使用 CMake 和 Visual Studio 编译源码:git clone https://github.com/oneapi-src/oneDNN.git cd oneDNN mkdir build && cd build cmake -G "Visual Studio 16 2019" -A x64 .. cmake --build . --config Release
- 下载预编译库
-
环境配置
- 将
include
目录添加到 Visual Studio 的 包含路径。 - 将
lib
目录添加到 库路径,并链接dnnl.lib
。 - 将
bin
目录下的dnnl.dll
复制到可执行文件目录或添加到系统PATH
。
- 将
2. oneMKL
-
安装方法
- 通过 Intel oneAPI 安装
下载 Intel® oneAPI Base Toolkit,安装时勾选 Intel® oneAPI Math Kernel Library。 - 独立安装(可选)
从 Intel 官网 下载独立安装包。
- 通过 Intel oneAPI 安装
-
环境配置
- 在 Visual Studio 中配置包含路径:
C:\Program Files (x86)\Intel\oneAPI\mkl\<version>\include
。 - 库路径:
C:\Program Files (x86)\Intel\oneAPI\mkl\<version>\lib\intel64
。 - 链接库:
mkl_sycl.lib
或mkl_intel_ilp64.lib
(根据精度需求选择)。
- 在 Visual Studio 中配置包含路径:
3. oneTBB
-
安装方法
- 通过 Intel oneAPI 安装
oneAPI Base Toolkit 包含 oneTBB,安装时勾选。 - 独立安装
从 GitHub Release 下载 Windows 预编译包。
- 通过 Intel oneAPI 安装
-
环境配置
- 包含路径:
C:\Program Files (x86)\Intel\oneAPI\tbb\<version>\include
。 - 库路径:
C:\Program Files (x86)\Intel\oneAPI\tbb\<version>\lib\intel64\vc14
。 - 链接库:
tbb.lib
,并将tbb.dll
添加到可执行文件目录。
- 包含路径:
二、使用示例(Visual Studio 项目)
1. oneDNN 示例(卷积操作)
#include <oneapi/dnnl/dnnl.hpp>
#include <iostream>
using namespace dnnl;
int main() {
engine eng(engine::kind::cpu, 0);
stream s(eng);
// 定义输入、权重、输出的内存
memory::dims input_dims = {1, 3, 224, 224};
auto input_mem = memory({{input_dims}, memory::data_type::f32, memory::format_tag::nchw}, eng);
auto weight_mem = memory({{64, 3, 3, 3}, memory::data_type::f32, memory::format_tag::oihw}, eng);
auto output_mem = memory({{1, 64, 222, 222}, memory::data_type::f32, memory::format_tag::nchw}, eng);
// 创建卷积算子
auto conv_desc = convolution_forward::desc(
prop_kind::forward_inference,
algorithm::convolution_auto,
input_mem.get_desc(),
weight_mem.get_desc(),
output_mem.get_desc(),
{1, 1}, // Stride
{0, 0} // Padding
);
auto conv_prim = convolution_forward(conv_desc, eng);
// 执行卷积
conv_prim.execute(s, {
{DNNL_ARG_SRC, input_mem},
{DNNL_ARG_WEIGHTS, weight_mem},
{DNNL_ARG_DST, output_mem}
});
s.wait();
std::cout << "Convolution completed!" << std::endl;
return 0;
}
- 项目配置
- 右键项目 → 属性 → C/C++ → 常规 → 添加 oneDNN 的
include
目录。 - 链接器 → 输入 → 附加依赖项:
dnnl.lib
。 - 将
dnnl.dll
复制到Debug
或Release
目录。
- 右键项目 → 属性 → C/C++ → 常规 → 添加 oneDNN 的
2. oneMKL 示例(矩阵乘法)
#include <CL/sycl.hpp>
#include <oneapi/mkl.hpp>
#include <iostream>
using namespace sycl;
using namespace oneapi::mkl;
int main() {
queue q;
const int m = 1024, n = 1024, k = 1024;
float *A = malloc_shared<float>(m * k, q);
float *B = malloc_shared<float>(k * n, q);
float *C = malloc_shared<float>(m * n, q);
// 初始化数据(示例)
for (int i = 0; i < m * k; i++) A[i] = 1.0f;
for (int i = 0; i < k * n; i++) B[i] = 2.0f;
// 执行矩阵乘法
blas::gemm(q, transpose::N, transpose::N, m, n, k, 1.0f, A, k, B, n, 0.0f, C, n);
q.wait();
std::cout << "C[0] = " << C[0] << std::endl; // 应输出 3*1024=3072(1*2累加1024次)
return 0;
}
- 项目配置
- 包含路径:添加 oneMKL 的
include
和 SYCL 头文件目录。 - 链接库:
mkl_sycl.lib
、mkl_intel_ilp64.lib
、mkl_core.lib
。 - 确保
sycl.dll
和mkl_rt.dll
在可执行目录。
- 包含路径:添加 oneMKL 的
3. oneTBB 示例(并行求和)
#include <tbb/parallel_reduce.h>
#include <tbb/blocked_range.h>
#include <vector>
#include <iostream>
using namespace tbb;
float parallel_sum(const std::vector<float>& data) {
return parallel_reduce(
blocked_range<size_t>(0, data.size()), 0.0f,
[&](const blocked_range<size_t>& r, float init) {
for (size_t i = r.begin(); i < r.end(); ++i) init += data[i];
return init;
},
[](float a, float b) { return a + b; }
);
}
int main() {
std::vector<float> data(1000000, 1.0f); // 100万个1.0
float sum = parallel_sum(data);
std::cout << "Sum: " << sum << std::endl; // 应输出1000000
return 0;
}
- 项目配置
- 包含路径:添加 oneTBB 的
include
目录。 - 链接库:
tbb.lib
。 - 将
tbb.dll
和tbbmalloc.dll
复制到输出目录。
- 包含路径:添加 oneTBB 的
三、常见问题解决
-
DLL 文件缺失
- 将
dnnl.dll
、tbb.dll
、mkl_rt.dll
等文件复制到可执行文件目录(如Debug
或Release
)。 - 或将它们的路径添加到系统环境变量
PATH
。
- 将
-
链接错误
- 确保库文件(
.lib
)路径正确,且架构一致(x64 需链接 x64 库)。
- 确保库文件(
-
性能优化
- 在 oneMKL 中,使用
mkl_intel_ilp64.lib
时需在代码中添加#define MKL_ILP64
。
- 在 oneMKL 中,使用
四、总结
步骤 | oneDNN | oneMKL | oneTBB |
---|---|---|---|
安装方式 | 预编译包/源码编译 | Intel oneAPI 安装 | 预编译包/oneAPI |
关键文件 | dnnl.lib , dnnl.dll | mkl_*.lib , mkl_rt.dll | tbb.lib , tbb.dll |
配置重点 | 内存布局与线程绑定 | 精度模式(ILP64/LP64) | 线程池大小控制 |
- 推荐工具:使用 Visual Studio 2022 和 Intel oneAPI 命令行工具(如
icl
编译器)以获得最佳兼容性。