2020-06-03に更新

8bit CPU ATmega328の除算性能を測定してみた

はじめに

ATmega328は Microchipの8bit CPU AVRの1種です。AVRは除算命令がなくArduinoで除算をするコードを書いた場合、どのくらいの性能になるのか測定しました。測定条件でソフトウェア処理が最適化されていないのでAVRのアセンブラを使って最適化をすれば、もっと高速になるはずですが、これはソフト開発環境Arduinoのソフトウエア除算性能の測定です。

測定条件

CPU : ATmega328 クロック 16MHz
ボード: Arduino
ソフト開発環境 : Arduino 1.8.10
性能を測定する除算 : 16bit ÷ 8bit / 24bit ÷ 8bit

測定コード(16bit÷8bit)

除算を1万回実行して、加算のみの場合との差分を除算1万回の実行時間とします。

void setup() {
    Serial.begin(9600);
    randomSeed(analogRead(0));
}

void loop() {
    unsigned long s, e, t;
    unsigned int i;
    unsigned short x,z;
    unsigned char y;

    t = millis();  /* dummy */      
    s = millis();
    for(i=0 ; i<10000 ; i++) {
        x = random(0,0xffff);
        y = random(2,0xff);
        z += x + y;    
    }
    e = millis();
    t = e - s;
    Serial.print("x="); Serial.print(x);
    Serial.print(" y=");  Serial.print(y);            
    Serial.print(" time1=");  Serial.print(t);      
    Serial.print("\n");

    s = millis();
    for(i=0 ; i<10000 ; i++) {
        x = random(0,0xffff);
        y = random(2,0xff);
        z += x / y;    
    }
    e = millis();
    t = e - s;
    Serial.print("x=");  Serial.print(x);
    Serial.print(" y=");  Serial.print(y);
    Serial.print(" z=");  Serial.print(z);             
    Serial.print(" time2=");
    Serial.print(t);      
    Serial.print("\n\n");
}

測定コード(24bit÷8bit)

除算を1万回実行して、加算のみの場合との差分を除算1万回の実行時間とします。

void setup() {
    Serial.begin(9600);
    randomSeed(analogRead(0));
}

void loop() {
    unsigned long s, e, t;
    unsigned int i;
    unsigned long x,z;
    unsigned char y;

    t = millis();  /* dummy */      
    s = millis();
    for(i=0 ; i<10000 ; i++) {
        x = random(0,0x7effff);
        y = random(0x7f,0xff);
        z += x + y;    
    }
    e = millis();
    t = e - s;
    Serial.print("x=");   Serial.print(x);
    Serial.print(" y=");   Serial.print(y);            
    Serial.print(" time1=");  Serial.print(t);      
    Serial.print("\n");

    s = millis();
    for(i=0 ; i<10000 ; i++) {
        x = random(0,0x7effff);
        y = random(0x7f,0xff);
        z += x / y;    
    }
    e = millis();
    t = e - s;
    Serial.print("x="); Serial.print(x);
    Serial.print(" y="); Serial.print(y);
    Serial.print(" z=");  Serial.print(z);             
    Serial.print(" time2=");
    Serial.print(t);      
    Serial.print("\n\n");
}

結果(16bit÷8bit)

除算1万回の実行時間は約128 [mS] 16MHzで動作しているのでサイクル数は2048000 cyc
除算1回のサイクル数は204.8 cyc
比較用の加算2サイクルの補正を追加すると
16bit÷8bit 除算1回のサイクル数は207 cyc

結果(24bit÷8bit)

除算1万回の実行時間は約373 [mS] 16MHzで動作しているのでサイクル数は5968000 cyc
除算1回のサイクル数は596.8 cyc
比較用の加算2サイクルの補正を追加すると
24bit÷8bit 除算1回のサイクル数は599 cyc
32bit÷16bitの性能と、ほとんど同じなので、24bit÷8bit用に除算ルーチンを作り直せば性能は向上するのではないだろうか。

ツイッターでシェア
みんなに共有、忘れないようにメモ

spinlock

8bit CPU WZetaの開発者です。もう一つ8bit CPU ICF3-Zをやっています。ICF3-Zは疑似パイプラインで高周波数動作。小型で高速を両立させたCPU。16bit÷8bit(条件つきで24bit÷8bit)の除算の高速性を活かして低周波数で動作させての低消費電力。https://icf3z.idletime.tokyo/

Crieitは誰でも投稿できるサービスです。 是非記事の投稿をお願いします。どんな軽い内容でも投稿できます。

また、「こんな記事が読みたいけど見つからない!」という方は是非記事投稿リクエストボードへ!

有料記事を販売できるようになりました!

こじんまりと作業ログやメモ、進捗を書き残しておきたい方はボード機能をご利用ください。
ボードとは?

コメント