Benchmark mikrokontrolérov: AVR, STM32, RP2040 a ESP32

Preberali sme s AI-kou výkon mikrokontrolérov, a prišli sme až k nápadu urobiť jednoduchý matematický benchmark. Ako záťaž sme použili výpočet prvočísel pomocou algoritmu Trial Division (testovanie deliteľnosti do odmocniny čísla). Algoritmus intenzívne využíva 32-bitovú celočíselnú aritmetiku, cykly a operáciu modulo (%).

Test teda počíta prvočísla, a testoval som v 3 rozsahoch. Do 200 tisíc, 1 milióna a 10 miliónov.

Kód vyzerá nasledovne:

unsigned long startTime;
unsigned long duration;

void setup() {
  Serial.begin(115200);
  while (!Serial); // Čakanie na sériový port
  delay(2000);

  Serial.println(F("\n========================================"));
  Serial.println(F("   HEAVY-DUTY PRIME NUMBER BENCHMARK    "));
  Serial.println(F("========================================"));
  
  #if defined(ESP32)
    Serial.println(F("Platform: ESP32 (240 MHz Dual Core)"));
  #elif defined(ARDUINO_ARCH_RP2040)
    Serial.println(F("Platform: RP2040 (133 MHz Dual Core)"));
  #elif defined(STM32F1xx) || defined(STM32F4xx) || defined(ARDUINO_ARCH_STM32)
    Serial.println(F("Platform: STM32"));
  #else
    Serial.println(F("Platform: AVR (Arduino Uno/Nano - 16 MHz)"));
  #endif
  
  Serial.println(F("----------------------------------------"));
  Serial.println(F("Spúšťam výpočet... (toto chvíľu potrvá)"));

  // Spustíme meranie v milisekundách
  startTime = millis();

  uint32_t limit = 10000000;
  uint32_t primeCount = 0;
  uint32_t lastPrime = 0;
  byte k = 0; 

  for (uint32_t n = 2; n <= limit; n++) {
    bool isPrime = true;
    for (uint32_t i = 2; i * i <= n; i++) {
      if (n % i == 0) {
        isPrime = false;
        break;
      }
    }
    if (isPrime) {
      // Serial.print(n); Serial.print(", "); k++; if (k == 20) {Serial.println(); k = 0;}   // Vypis prvocisel na konzolu
      primeCount++;
      lastPrime = n;
    }
  }

  duration = millis() - startTime;

  // --- VÝPIS VÝSLEDKOV ---
  Serial.println();
  Serial.println(F("----------------------------------------"));
  Serial.print(F("Testovany limit:     ")); Serial.println(limit);
  Serial.print(F("Najdenych prvocisel: ")); Serial.println(primeCount);
  Serial.print(F("Posledne prvocislo:  ")); Serial.println(lastPrime);
  Serial.print(F("Celkovy cas (ms):    ")); Serial.println(duration);
  Serial.print(F("Celkovy cas (s):     ")); Serial.println(duration / 1000.0, 3);
  Serial.println(F("========================================"));
  Serial.println(F("Benchmark dokončený!\n"));
}

void loop() {
}

Nechal som ho zbehnúť na vývojových doskách čo som našiel doma. Najprv 8bitové Arduino Uno s ATmega328 na 16MHz, ESP32-WROOM-32 na takte 20MHz a tiež 240MHz, Raspberry Pico RP2040 pretaktovanú na 200MHz a STM32L552ZEQ6 na takte 110MHz. Všetky mikrokontroléry okrem ATmega328 sú 32bitové a rozdiel je priepastný. AVR nemá hardvérovú deličku pre 32-bitové čísla a operácia % (n % i) sa na 8-bitovom procesore skladá z obrovského množstva softvérových inštrukcií posunov a odčítaní. Preto na Arduine som ani nespustil test do 10 miliónov, výsledku by som sa asi nedožil.

MikrokontrolérTakt jadraČas do 200kČas do 1MČas do 10M
ESP32-WROOM240 MHz0,48 s4,62 s1 min 59 s
STM32110MHz1,06 s9,56 s4 min 13 s
RP2040 (Raspberry Pi Pico)200 MHz (pretaktované)1,16 s10,91 s4 min 40 s
ESP32-WROOM20 MHz (podtaktované)6,09 s57,86 s24 min 54 s
Arduino Uno (ATmega328P)16 MHz5 min 09 s48 min 54 snetestované

Pridaj komentár

Vaša e-mailová adresa nebude zverejnená. Vyžadované polia sú označené *