我正在尝试通过将其移植到C ++来加速一些Matlab代码,并且我发现C ++中非常简单的操作比在Matlab中慢得多。即,将整数数组转换为浮点数。我正在使用Intel Parallel Studio 2018和MKL以及TBB。
Matlab中的这一行在我的笔记本电脑上平均需要6毫秒(Mac OS 10.13):
spec = single(spec_int); % spec_int is 1000x4096 uint16
朴素的方法(单循环)大约需要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速度?
答案 0 :(得分:2)
总结:你可能正在测量噪音:
我相当确定你正在处理的只是来自先前(隐式)matlab操作的内存缓存加速它。我重写了你的天真实现以使用查找表(因此它是一个简单的赋值,没有类型转换)。这并没有加快速度。值得注意的是。
接下来,我运行了一个类似的(但不同的 - 以防止它被优化掉)循环和定时。它运行很多更快:
int main()
{
float index[65537] ;
for (int i = 0; i < 65537; i++)
index[i] = i;
uint16_t *pi = new uint16_t[4096 * 1000];
memset(pi, 0, sizeof(pi));
float *pf = new float[4096 * 1000];
memset(pf, 0, sizeof(pf));
clock_t begin = clock();
for (int i = 0; i < 4096 * 1000; ++i)
{
pf[i] = index[pi[i]]; //no conversion...simple copy(and not faster)
}
clock_t end = clock();
clock_t begin2 = clock();
for (int i = 0; i < 4096 * 1000; ++i)
{
pf[i] = index[pi[i]+1];
}
clock_t end2 = clock();
printf("%d\n", (long)end - begin);
printf("%d\n", (long)end2 - begin2);
}
输出:
9
2
我通过实际的浮点转换获得了类似的结果。所以我的理论是Matlab只是执行一些操作,在执行你正在计时的操作之前获得重要的内存缓存(顺便说一下,你可能正在使用不同的时间机制)。
这完全是猜测,但如果没有matlab专家的帮助,这可能是最好的。
上述C#
,btw:12, 4
的输出。