« ATtiny85でカラーLEDテープを光らせてみる | トップページ | 24VでLチカ »

2021年2月 5日 (金)

Arduinoで使える乱数の実行時間

2021年2月3日:FastLED-masterにある8bit乱数関数
この続き・・・
偏りの少ない乱数値の発生、桁数8bitのrand8()を使うと
数の出現がおかしくなることが分かりました。
  ※256を割れる値で乱数を得る場合はok。
  ※なんといっても早い。

速度を追い求めないなら、今までどおり16bitのrand()
あるいは32bitのrandom()
その実行速度をオシロで見てみました。
こんなスケッチ。

/*****  rand()とrandom()の速度を見てみる *****/
// タイミング確認パルス
#define PB0_H (PORTB |= (1 << PB0)) // (!!!)PB0:D8 H/L
#define PB0_L (PORTB &= ~(1 << PB0))
#define PB1_H (PORTB |= (1 << PB1)) // (!!!)PB1:D9 H/L
#define PB1_L (PORTB &= ~(1 << PB1))
#define PB2_H (PORTB |= (1 << PB2)) // (!!!)PB2:D10 H/L
#define PB2_L (PORTB &= ~(1 << PB2))
#define PB3_H (PORTB |= (1 << PB3)) // (!!!)PB3:D11 H/L
#define PB3_L (PORTB &= ~(1 << PB3))
/***** セットアップ *****/
void setup()
{
pinMode(8, OUTPUT); // タイミングチェック用
pinMode(9, OUTPUT);
pinMode(10, OUTPUT);
pinMode(11, OUTPUT);
}
/***** ループ *****/
void loop()
{
volatile byte r;
volatile uint16_t r1; // rand() 結果
volatile uint8_t r2; // rand() % r 結果
volatile uint32_t r3; // random() 結果
volatile uint8_t r4; // random() % r 結果
r = 1 + (rand() % 255); // 1~255を乱数で
PB0_H; // (!!!)
r1 = rand(); // 16bit乱数
PB0_L;
PB1_H; // (!!!)
r2 = r1 % r; // rand() % r, 16bit/8bit
PB1_L;
PB2_H; // (!!!)
r3 = random(); // 32bit乱数
PB2_L;
PB3_H; // (!!!)
r4 = r3 % r; // random() % r, 32bit/8bit
PB3_L;
}

得られた波形。
 ch1:16bitのrand()
 ch2:16bit % 8bit 剰余の実行時間。
 ch3:32bitのrandom()
 ch4:32bit % 8bitの実行時間

B000_20210205091701

rand()もrandom()も同じような実行時間です。
剰余を得る時間が異なります。
多桁の割り算は時間がかかります。

|

« ATtiny85でカラーLEDテープを光らせてみる | トップページ | 24VでLチカ »

Arduino」カテゴリの記事

コメント

剰余の代わりに、
 乗算/32768、乗算/0x8000000
に変えてみると。。。

 r2 = r1 % r; // rand() % r, 16bit/8bit
  ↓
 r2 = ((uint32_t)r1 * r) / 32768;

 r4 = r3 % r; // random() % r, 32bit/8bit
  ↓
 r4 = ((uint64_t)r3 * r) / 0x80000000;

r2のほうは13us→9usに
r4のほうは39us→22usに
と、ちょいスピードアップ。
多桁の乗除算、8bitマイコンには荷が重い。

投稿: 居酒屋ガレージ店主(JH3DBO) | 2021年2月 5日 (金) 11時21分

コメントを書く



(ウェブ上には掲載しません)




« ATtiny85でカラーLEDテープを光らせてみる | トップページ | 24VでLチカ »