BETA

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

投稿日:2020-01-12
最終更新:2020-01-12

はじめに

ATmega328は Microchipの8bit CPU AVRの1種です。AVRは除算命令がなくArduinoで除算をするコードを書いた場合、どのくらいの性能になるのか測定しました。ソフト開発環境Arduinoのソフトウエア除算性能の測定です。

測定条件

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

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

技術ブログをはじめよう Qrunch(クランチ)は、プログラマの技術アプトプットに特化したブログサービスです
駆け出しエンジニアからエキスパートまで全ての方々のアウトプットを歓迎しております!
or 外部アカウントで 登録 / ログイン する
クランチについてもっと詳しく

この記事が掲載されているブログ

なにか思いついたことを不定期に更新。

よく一緒に読まれる記事

0件のコメント

ブログ開設 or ログイン してコメントを送ってみよう