7

この質問で述べたように、何百万回も実行されるいくつかの Matlab コードがあります。

それが役立つかどうかを確認するために、それをmex化しようとしています。ここで、Matlab Coder ツールを使用して Matlab コードからコードを生成すると、コードは一般的に合理的ですが、Matlab コードのこの 1 行 (下の最初の行の C++ コメント内) がこの怪物を生み、その理由がわかりません。その複雑さを理解し、軽減するための助けをいただければ幸いです。

文脈上、d は 2 次元行列で、s1 は行ベクトルです。s1_idx は、前述の C++ コードで length(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];
}
4

3 に答える 3

4

これは、実際に達成したいことに対して生成された非常に面白いコードです。0 から k までの整数を配列に詰め込みたいだけです。ただし、コード ジェネレーターは、一般的なケースに対処するように構築されています。したがって、生成されたコードには 3 つの部分があります。

  1. 左側のどこに右側の要素を配置するかを指定するインデックスの配列を作成します。という表現を使用しました:が、別の表現を使用することもできました。コード ジェネレーターは、次のようなことを行うために準備する必要がありますd(length(s1):0, 1)=0:length(s1)
  2. 右辺の値の配列を作成します。連続した整数を処理するだけですが、コード ジェネレーターは double を処理する準備ができており、double の範囲から値を作成するときに、おかしな丸めの問題が発生する可能性があります。あらゆる種類のエッジケースをチェックしています。
  3. 最後に、手順 1 で作成した配列によってインデックス付けされた左側のメモリ スロットに右側の値を実際に割り当てるループがあります。

最終的に、必要なのは次のことだけかもしれません。

cdiff = s1_idx_0 - 1;
for (nm1d2 = 0; nm1d2 <= cdiff; nm1d2++) {
   SD->f0.d_data[nm1d2] = nm1d2;
}
于 2012-10-18T15:01:14.220 に答える
2

MatLabは、特別な数学関数で動作するように設計された特別なケースです。内部的には、プロセッサが理解できる多くのマシンコードに変換されていることに気づきます。

SOには、同じことを尋ねる質問がたくさんあります。「なぜXXはMatlabで非常に簡単で、C ++では非常に難しいのですか?」Matlabはこのために設計されたのに対し、C++は汎用言語です。

Matlabの開発者は、この機能を1行で使用する方法を提供するために、これらの大きなコードシートを作成する必要がありました。C ++には標準ライブラリに含まれていないため、自分で作成する必要があります。

さて、簡単な例を見てみましょう。ユーザーAとBが2次方程式を解きたいとします。ユーザーAは数学パッケージを使用しており、彼がしなければならないのは書くことだけです

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

一方、ユーザーBはC ++を使用しており、判別式をカウントし、値を計算して(もちろん、負の判別式についても心配する必要があります)、それらを出力する関数を作成する必要があります。数学パッケージはユーザーAに対してすでに実行されています。これは実際には多くのコードです。これは、がすぐにグーグルで検索した例です。

ここで、ユーザーAが「ねえ、B、なぜそんなに多くのコードを書く必要があるのか​​?私はたった1行でそれを行うことができる!」と言っていると想像してみてください。そしてこれはあなたの場合になります;)

また、人間による読みやすさと理解のしやすさについて話す場合、自動生成されたコードが常に最高のコードであるとは限らないことを忘れないでください。

于 2012-10-18T12:22:15.173 に答える