XC8の「クセ」など
2013-09-18
最近使い倒しているXC8とその関連について、忘れそうな些細なことを記録しておきます。
◆ 変数を使うか使わないかの差異
当たり前と言えば当たり前ですが、コンパイラのクセを理解して使うことで、無闇に大きなプログラムにしない工夫はできるわけですが、とりわけ「変数」を使う、使わないという根幹的な判断は、やはり試してみないと判らない・・・ということが判りました。
例えば配列のインデックスについて、インデックスの要素番号を示すものを計算して記述する以下のような場面では、どちらのパターンが効率が良いか、やはり試してみないと判らないようです。
きっと規則性はあるんだと思いますが、まぁ上記のように2パターンをコンパイルして短い方を選んでいくという作業で切り分けするのが簡単。全く同じ場合もあるんですが、数ステップの差が出る場合があります。XC8の無償版は肥大化傾向にありますから、小さなメモリでは直ぐに一杯に・・・暇潰しに如何ですか
◆ const 定義が256バイトまでとは・・・
これ、結構な足枷です。テーブル論理重視でコーディングするとif 文等の分岐が減って論理バグが少なくなるため、結構初期値有りデータは使います。const を付けないとデータエリアをジャンジャン食い潰すためどうしても使いたいんですが、コンパイラの仕様だから「しようがない」・・・って、駄洒落かよぅ
◆ やはりライブラリ関数は巨大過ぎ
EEPROMのちょっとした読み書きライブラリについては少し前に記事にしたように、やはりライブラリ関数は「プログラムの大きさ」の観点ではあまり好ましくない感じです。勿論メモリさえ大きければ、こうした部分を自前で作った挙げ句に潜むバグは撃滅できますから一長一短ですが、何にせよでか過ぎ・・・って、まぁこれも「しようがない」・・・って、続けんのかよぅ
◆ 汎用変数を用意するといいかも・・・
PIC如きのプログラムで、リエントラントな関数がどうしても必要ってなことにはまぁならんでしょう。そうすると、割込処理との競合(共用)だけを考慮して、あまり意味を持たないワーク変数はまとめてしまうという手が使えます。何気なく関数内でポツポツ使うワーク変数(for 文のループ回数用の変数などなど)は、代表名を決めてしまい「グローバル変数」として1つ用意しておけば十分でしょう。この辺り、あまり「プログラムの美しさ」を重視せずに「自分のローカルルール」を作った方が良さそうですよ。
◆ とにかく四則演算は注意して使うこと
PICに関する解説ホームページの各所に丁寧な説明が見られますんで、そちらをご覧下さい・・・なんですが、「符号無しchar」に拘りつつ、乗除算を無碍に使わぬように工夫すれば、メチャメチャ大きくはならないしスピード的にも有利。その分クロックを落とすとさらに「省エネ」のオマケが貰えます
◆ XC8無償版は「アセンブラの倍」と思え
純粋に二倍・・・とはなりませんが、やはりかなり冗長です。多分、最も高価な有料版だと半分になる・・・という謳い文句そのものだと思います。
アセンブルリストが吐き出せれば、ソースベースで自動的に不要な処理をちょん切ったりできそうですが、どうにかならないかしらん・・・と頭をひねっています。
◆ ポインタも使い方次第
構造体配列などは、そのまま配列番号でインデックスせずポインタで扱ってやると、吐き出されるニーモニックがかなり小さくなる場合があります。見通しが悪くなるんで良し悪しですが、お好きな方はお試しあれ。
自分的にショックだったのは、やはり「const 定義の256バイト制限」です。新しいPICはプログラムエリアのインデックスができますから、この辺りはアセンブラに逃げるのも有りかもしれませんが、ちょっと萎えちゃった部分でもあります。
◆ 変数を使うか使わないかの差異
当たり前と言えば当たり前ですが、コンパイラのクセを理解して使うことで、無闇に大きなプログラムにしない工夫はできるわけですが、とりわけ「変数」を使う、使わないという根幹的な判断は、やはり試してみないと判らない・・・ということが判りました。
例えば配列のインデックスについて、インデックスの要素番号を示すものを計算して記述する以下のような場面では、どちらのパターンが効率が良いか、やはり試してみないと判らないようです。
unsigned char n,idx,ans; unsigned char tbl[10]; : n = idx << 3; // A ans = tbl[n]; ans = tbl[idx << 3]; // B |
きっと規則性はあるんだと思いますが、まぁ上記のように2パターンをコンパイルして短い方を選んでいくという作業で切り分けするのが簡単。全く同じ場合もあるんですが、数ステップの差が出る場合があります。XC8の無償版は肥大化傾向にありますから、小さなメモリでは直ぐに一杯に・・・暇潰しに如何ですか

◆ const 定義が256バイトまでとは・・・
これ、結構な足枷です。テーブル論理重視でコーディングするとif 文等の分岐が減って論理バグが少なくなるため、結構初期値有りデータは使います。const を付けないとデータエリアをジャンジャン食い潰すためどうしても使いたいんですが、コンパイラの仕様だから「しようがない」・・・って、駄洒落かよぅ

◆ やはりライブラリ関数は巨大過ぎ
EEPROMのちょっとした読み書きライブラリについては少し前に記事にしたように、やはりライブラリ関数は「プログラムの大きさ」の観点ではあまり好ましくない感じです。勿論メモリさえ大きければ、こうした部分を自前で作った挙げ句に潜むバグは撃滅できますから一長一短ですが、何にせよでか過ぎ・・・って、まぁこれも「しようがない」・・・って、続けんのかよぅ

◆ 汎用変数を用意するといいかも・・・
PIC如きのプログラムで、リエントラントな関数がどうしても必要ってなことにはまぁならんでしょう。そうすると、割込処理との競合(共用)だけを考慮して、あまり意味を持たないワーク変数はまとめてしまうという手が使えます。何気なく関数内でポツポツ使うワーク変数(for 文のループ回数用の変数などなど)は、代表名を決めてしまい「グローバル変数」として1つ用意しておけば十分でしょう。この辺り、あまり「プログラムの美しさ」を重視せずに「自分のローカルルール」を作った方が良さそうですよ。
◆ とにかく四則演算は注意して使うこと
PICに関する解説ホームページの各所に丁寧な説明が見られますんで、そちらをご覧下さい・・・なんですが、「符号無しchar」に拘りつつ、乗除算を無碍に使わぬように工夫すれば、メチャメチャ大きくはならないしスピード的にも有利。その分クロックを落とすとさらに「省エネ」のオマケが貰えます

◆ XC8無償版は「アセンブラの倍」と思え

純粋に二倍・・・とはなりませんが、やはりかなり冗長です。多分、最も高価な有料版だと半分になる・・・という謳い文句そのものだと思います。
アセンブルリストが吐き出せれば、ソースベースで自動的に不要な処理をちょん切ったりできそうですが、どうにかならないかしらん・・・と頭をひねっています。
◆ ポインタも使い方次第
構造体配列などは、そのまま配列番号でインデックスせずポインタで扱ってやると、吐き出されるニーモニックがかなり小さくなる場合があります。見通しが悪くなるんで良し悪しですが、お好きな方はお試しあれ。
自分的にショックだったのは、やはり「const 定義の256バイト制限」です。新しいPICはプログラムエリアのインデックスができますから、この辺りはアセンブラに逃げるのも有りかもしれませんが、ちょっと萎えちゃった部分でもあります。