繁体   English   中英

C和Matlab:为什么Matlab中的这一行在Matlab Coder生成的C ++代码中变得如此之多?

[英]C and Matlab: Why does this one line in Matlab become so many lines in C++ code generated by Matlab Coder?

我有一些运行数百万次的Matlab代码,如本问题所述: Matlab:从循环中重复调用相同的mex函数会产生太多的开销吗?

我正在尝试mex-ify,看看是否有帮助。 现在,当我使用Matlab Coder工具从Matlab代码生成代码时,代码通常是合理的,但是这一行Matlab代码(在下面第一行的C ++注释中)会产生这种怪异,我不知道为什么。 任何帮助理解和降低其复杂性将不胜感激。

对于上下文,d是二维矩阵,s1是行向量。 在前面的C ++代码中,s1_idx被指定为长度(s1)+ 1,

/* d(:, 1) = 0:length(s1); */
cdiff = s1_idx_0 - 1;
for (nm1d2 = 0; nm1d2 <= cdiff; nm1d2++) {
   tmp_data[nm1d2] = nm1d2;
}
ndbl = (int32_T)muDoubleScalarFloor((real_T)s1_sizes[1] + 0.5);
apnd = ndbl;
cdiff = ndbl - s1_sizes[1];
if (muDoubleScalarAbs((real_T)cdiff) < 4.4408920985006262E-16 * (real_T)s1_sizes[1]) {
   ndbl++;
   apnd = s1_sizes[1];
} else if (cdiff > 0) {
   apnd = ndbl - 1;
} else {
   ndbl++;
}
if (ndbl > 0) {
   b_tmp_data[0] = 0.0;
   if (ndbl > 1) {
       b_tmp_data[ndbl - 1] = (real_T)apnd;
       nm1 = ndbl - 1;
       nm1d2 = nm1;
       nm1d2 = (int32_T)((uint32_T)nm1d2 >> 1);
       for (cdiff = 1; cdiff <= nm1d2 - 1; cdiff++) {
           b_tmp_data[cdiff] = (real_T)cdiff;
           b_tmp_data[(ndbl - cdiff) - 1] = (real_T)(apnd - cdiff);
       }
       if (nm1d2 << 1 == nm1) {
           b_tmp_data[nm1d2] = (real_T)apnd / 2.0;
       } else {
           b_tmp_data[nm1d2] = (real_T)nm1d2;
           b_tmp_data[nm1d2 + 1] = (real_T)(apnd - nm1d2);
       }
   }
}
cdiff = s1_idx_0 - 1;
for (nm1d2 = 0; nm1d2 <= cdiff; nm1d2++) {
   SD->f0.d_data[tmp_data[nm1d2]] = b_tmp_data[nm1d2];
}

对于你真正想要实现的目标,这是非常有趣的生成代码。 您只想将整数0到k填充到数组中。 但是代码生成器是为了处理一般情况而构建的。 所以生成的代码有三个部分:

  1. 创建一个索引数组,指定左侧的元素从右侧开始的位置。 你使用了: expression,但是你可以使用其他东西。 代码生成器必须为你准备像d(length(s1):0, 1)=0:length(s1)
  2. 为右侧创建一个值数组。 你只是做顺序整数,但代码生成器准备处理双打,当从一系列双打创建值时,你可能会有有趣的舍入问题。 它正在检查各种边缘情况。
  3. 最后,有一个循环实际上将右侧的值分配给左侧的内存插槽,由步骤1中创建的数组索引。

最后,您可能只需要:

cdiff = s1_idx_0 - 1;
for (nm1d2 = 0; nm1d2 <= cdiff; nm1d2++) {
   SD->f0.d_data[nm1d2] = nm1d2;
}

MatLab是一个特殊的案例,旨在使用特殊的数学函数。 你确实意识到,引擎盖下的东西仍然被翻译成许多处理器可以理解的机器代码。

在SO上有很多问题要求同样的事情:“为什么XX在Matlab中很容易做到,在C ++中如此难以实现?”。 因为Matlab是为此而设计的 ,而C ++是一种通用语言。

Matlab开发人员必须编写这些大型代码表,以便为您提供仅使用一行的方法来使用此功能。 C ++在标准库中没有它,因此您需要自己创建它。

好吧,举一个简单的例子。 假设用户A和B想要求解二次方。 用户A正在使用数学包,他所要做的就是写

FIND x IN 2x 2 + 6x + 3 = 0

另一方面,用户B正在使用C ++,他必须编写一个函数来计算判别式,计算值(他当然也要担心负判别)并输出它们,这是开发人员的事情。数学包已经为用户A完成了。这真的是很多代码, 是我快速搜索一个例子。

现在假设用户A说“嘿,B,你为什么要编写这么多代码呢?我只能在一行中做到这一点!” 这将是你的情况;)

另外不要忘记,如果你谈论人类可读性和易于理解的话,自动生成的代码并不总是最好的代码。

我迟到了这个派对,但现有的答案集中在它为什么会发生,而不讨论你能做些什么。

如果您知道哪一行会导致看起来很奇怪,看起来很乱的C代码,那么您应该尝试更改该行。 代替:

d(:, 1) = 0:length(s1);

要尝试的一件事是删除对变量s1的依赖:

d(:, 1) = 0:size(d,1);

另一种选择是编写一个几乎可以直接转换为C的简单循环。希望codegen能够提供非常相似和简单的C代码。

for i = 0:size(d,1)
    d(i,1) = i;
end

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM