ESP32 vs. Rapsberry Pi 2B sebesség WTF

Vettem egy ESP32 boardot, és gondoltam megpróbálom összevetni a sebességét a raspberrymmel. Erre írtam egy nagyon egyszerű prímszámkereső programot, és eléggé meglepett az eredmény, tekintve, hogy mindkettő kb. 20-22 másodperc alatt végzett. Nem tudom hova tenni a dolgot, mivel az ESP32 csak 240 MHz-es. Mi lehet ennek az oka? :F

ESP32 Arduino kód:

void setup()
{
Serial.begin(112500);
delay(1000);

unsigned long start = millis();
int primes = 0;

for(unsigned int i = 2; i < 100000; i++)
{
bool is_prime = true;

for(unsigned int j = 2; j < i; j++)
{
if(0 == (i % j))
{
is_prime = false;
break;
}
}

if(is_prime) primes++;
}

Serial.println(millis() - start);
Serial.println(primes);
}

void loop()
{
}

raspberrys kód gcc -std=c99 -O3 -o prime -Wall prime.c opcióval fordítva:

#include <stdio.h>

int main()
{
int primes = 0;

for(unsigned int i = 2; i < 100000; i++)
{
int is_prime = 1;

for(unsigned int j = 2; j < i; j++)
{
if(0 == (i % j))
{
is_prime = 0;
break;
}
}

if(is_prime) primes++;
}

printf("%d\n", primes);

return 0;
}

A htop szerint egy magot kimaxol a progi, és az eredmények megegyeznek, szóval nem kóklerkedi el a munkát egyik sem.

Szerk.:

Azt hiszem, rájöttem a megoldásra: az ESP32-ben levő Tensilica Xtensa LX6-nak van egy REMU nevű assembly utasítása:[476. oldal], amely az osztás utáni maradékot adja vissza, ez gondolom a kriptográfiai függvények gyorsításához kell, ARM-en viszont nem találtam ilyen utasításra példát, és az egész egy __aeabi_uidivmod hívásra fordul, aminek ha jól látom, elég költséges az komplementációja.

  • weiss

    addikt

    LOGOUT blog

    válasz joysefke #1 üzenetére

    1/ Ez akkor lenne érdekes, ha egy ideális prímkereső implementációt írnék. Most csak annyi volt a lényeg, hogy egy szálon mekkora a teljesítmény különbség.

    2/ Valóban, de így pont a raspynak kellene sokkal gyorsabbnak lennie.

    3/ Jogos :)

  • joysefke

    veterán

    Erre én is kíváncsi vagyok, most vettem egy Pi3 plusz-t :)

    amit én laikusként problémának látok, hogy

    1, csak egyetlen szálon futtatod a programot. Korrekt úgy lenne a dolog (az algoritmus primitívségét figyelmen kívül hagyva), hogy ha az elején lekérdeznéd mennyi logikai processzor (a Pi-ben ez 4db) van és annyi szálat indítanál, ahol mindegyik szál csupán a megfelelő modulójú számokra ellenőrizné a prímséget, a végén pedig összesítenéd a részeredményeket.

    2, az egész program mindenestől belefér az egyetlen használt logikai processzor gyorsítótárába, ez nem feltétlenül életszerű...

    3, Nyilván nem 20mp-t számít (lehet 20ms-t sem), de ha a konzolra írás idejét nem számoltad bele az Arduinos benchmarkban, akkor a Pi-vel se mérd bele a futási időbe:

    Serial.println(millis() - start);
    Serial.println(primes);

    itt a millis()-start utasítás végrehajtásával már megvan a benchmark eredménye, amit a kettő darab konzolra írás már nem befolyásol. a Pi-s példában pedig előbb írsz a konzolra, majd visszatér a program és nyilván csupán ez után mérsz egy időt ami nem a nettó futási időd lesz, hanem (feltételezem) az az idő ami eltelik amennyi idő alatt az egész program visszaadja a vezérlést a linuxos parancsértelmezőnek.

    szerk: igen olvastam a végét :)

Tovább a fórumba.