【发布时间】:2018-05-19 08:39:08
【问题描述】:
我正在尝试通过将一些 Matlab 代码移植到 C++ 来加速它,我发现在 C++ 中非常简单的操作比在 Matlab 中慢得多。即,将整数数组转换为浮点数。我正在使用带有 MKL 和 TBB 的 Intel Parallel Studio 2018。
Matlab 中的这一行在我的笔记本电脑(Mac OS 10.13)上平均需要 6 毫秒:
spec = single(spec_int); % spec_int is 1000x4096 uint16
naive 方法(单循环)大约需要 9 毫秒(不包括内存分配和初始化):
uint16_t *spec_int = (uint16_t *) MKL_malloc(4096 * 1000 * sizeof(uint16_t), 64);
float *spec = (float *) MKL_malloc(sizeof(float) * FRAME_SIZE, 64);
// Initialize spec_int
for(MKL_INT i = 0; i<FRAME_SIZE; i++)
spec[i] = spec_int[i];
在 TBB 中使用 parallel_for 大约需要 13 毫秒:
tbb::parallel_for( size_t(0), size_t(FRAME_SIZE), [&]( size_t i ) {
spec[i] = spec_int[i];
} );
我很困惑。我究竟做错了什么?如何在 C++ 中匹配 Matlab 速度?
【问题讨论】:
-
编译器很可能正在对您的幼稚方法进行矢量化。您在编译时使用什么优化级别?
-
我无法想象并行版本会更快,除非向量很大
-
您当然应该为循环变量和索引使用
int,而不是任何其他类型,例如MKL_INT,不管它是什么。 -
@NathanOliver -O3。是的,可能有自动矢量化。这是完整的编译行:icc -DMKL_ILP64 -mkl=parallel -O3 -I/opt/intel/compilers_and_libraries_2019.0.041/mac/mkl/include -I/opt/intel/compilers_and_libraries_2019.0.041/mac/tbb/include -std =c++11 -o gdocm_cpu main.cpp -L/opt/intel/compilers_and_libraries_2019.0.041/mac/mkl/lib -L/opt/intel/compilers_and_libraries_2019.0.041/mac/tbb/lib -Wl,-rpath,/ opt/intel/compilers_and_libraries_2019.0.041/mac/mkl/lib -Wl,-rpath,/opt/intel/compilers_and_libraries_2019.0.041/mac/tbb/lib -ltbb -lstdc++ -lpthread -lm -ldl
-
@RichardHodges 英特尔文档指出:“通常循环需要至少一百万个时钟周期才能使其值得使用 parallel_for。例如,在 2 GHz 处理器上至少需要 500 微秒的循环可能会从 parallel_for 中受益。”我有大约 400 万个元素,循环需要 9 毫秒。所以我期待至少有一些改进。