簡體   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