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用に除算ルーチンを作り直せば性能は向上するのではないだろうか。

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

canal

自作 8bit CPU ICF3-Zをやっています。疑似パイプラインで高周波数動作。小型で高速を両立させたCPU。 16bit÷8bit(条件つきで24bit÷8bit)の除算の高速性を活かして低周波数で動作させての低消費電力。 本命はサーバー向けの高効率なモンゴメリ乗算器を搭載した暗号プロセッサによるSSLアクセラレータ。SnakeCube(ICF3-F)という名前で、現在、開発を進めています。

Crieitは個人で開発中です。 興味がある方は是非記事の投稿をお願いします! どんな軽い内容でも嬉しいです。
なぜCrieitを作ろうと思ったか

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

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

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

関連記事

コメント