C ++优化从int到float

时间:2018-05-18 21:18:26

标签: c++ matlab tbb intel-mkl

我正在尝试通过将其移植到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速度?

1 个答案:

答案 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的输出。