Op deze website gebruiken we cookies om content en advertenties te personaliseren, om functies voor social media te bieden en om ons websiteverkeer te analyseren. Ook delen we informatie over uw gebruik van onze site met onze partners voor social media, adverteren en analyse. Deze partners kunnen deze gegevens combineren met andere informatie die u aan ze heeft verstrekt of die ze hebben verzameld op basis van uw gebruik van hun services. Meer informatie.

Akkoord

Vraag & Antwoord

Programmeren

[C++/Assembly] Detecteren FSB en/of Bus Speed

Ben Lankamp
8 antwoorden
  • Weet iemand hoe ik de FSB en/of bus speed kan meten via C++/assembly? Ik kan al wel de total cpu-speed meten (bijv. 3076mhz), maar nog niet de FSB.
  • Vet ;-)
    Ik kan je helaas niet verder helpen…. ben geen ASM programmeur (wel C++)
    Maar zou je mij misschien willen vertellen hoe je dat gedaan hebt?
  • CPU speed meten is vrij simpel. Als je tenminste iets af weet van processoren. Elke instructie (in ASM) kost een bepaalt aantal 'processor-klikken'. Door middel van de teller van het aantal klikjes en de frequentie van die klikjes op te vragen kan je de CPU speed berekenen.

    De code:

    [code:1:cc1b09eaaf] // cycle counter
    inline __int64 GetCycleNumber()
    {
    __asm
    {
    RDTSC
    }
    }

    (…)

    // detect CPU speed
    LARGE_INTEGER t1, t2, tf;
    __int64 c1, c2;

    QueryPerformanceFrequency (&tf;);
    QueryPerformanceCounter (&t1;);
    c1 = GetCycleNumber ();

    _asm {
    MOV EBX, 5000000
    WaitAlittle:
    DEC EBX
    JNZ WaitAlittle
    }

    QueryPerformanceCounter (&t2;);
    c2 = GetCycleNumber ();

    double cpuspeed = (double) ((c2 - c1) * tf.QuadPart /
    (t2.QuadPart - t1.QuadPart) / 1000000);[/code:1:cc1b09eaaf]

    Ondertussen ben ik ook al zover dat ik van de CPU kan vragen hoe 'ie heet, door wie 'ie is gemaakt, en hoeveel L1 en L2 cache 'ie heeft.
  • Ik snap ongeveer wel wat je bedoelt.
    Wat houden alleen die QueryPerformanceCounter etc. functie's in??
  • [quote:4ad4277878="phaas"]Vet ;-)
    Ik kan je helaas niet verder helpen…. ben geen ASM programmeur (wel C++)
    Maar zou je mij misschien willen vertellen hoe je dat gedaan hebt?[/quote:4ad4277878]


    Pentium-only code door RDTSC opcode…
    [code:1:4ad4277878]
    function GetCPUSpeed: Double;
    const
    DelayTime = 500;
    var
    TimerHi : DWORD;
    TimerLo : DWORD;
    PriorityClass : Integer;
    Priority : Integer;
    begin
    PriorityClass := GetPriorityClass(GetCurrentProcess);
    Priority := GetThreadPriority(GetCurrentThread);
    SetPriorityClass(GetCurrentProcess, REALTIME_PRIORITY_CLASS);
    SetThreadPriority(GetCurrentThread, THREAD_PRIORITY_TIME_CRITICAL);
    Sleep(10);
    asm
    DW 310Fh // rdtsc
    MOV TimerLo, EAX
    MOV TimerHi, EDX
    end;
    Sleep(DelayTime);
    asm
    DW 310Fh // rdtsc
    SUB EAX, TimerLo
    SBB EDX, TimerHi
    MOV TimerLo, EAX
    MOV TimerHi, EDX
    end;
    SetThreadPriority(GetCurrentThread, Priority);
    SetPriorityClass(GetCurrentProcess, PriorityClass);
    Result := TimerLo / (1000.0 * DelayTime);
    end;



    // Usage …


    LabelCPUSpeed.Caption := Format('CPU speed: %f MHz', [GetCPUSpeed]);
    [/code:1:4ad4277878]
  • // h4xX0r
    Die methode is eigenlijk niet goed, omdat je gebruik maakt van threads, en aangezien Windows met threads nogal eens allerlei onnodige rotzooi uitvoert, die ook processor-klikken kosten, kan je soms rare resultaten (zelfs op een Pentium, met name de oudere) krijgen. Daarnaast is deze methode, zoals je zelf al aangeeft, Intel-only. Het doet z'n werk wel goed op de nieuwere Pentiums (al kost het een stuk meer processorkracht, niet merkbaar maar 't gebeurt wel), maar is dus niet efficient en globaal genoeg (en dat is wat programmeren óók om draait: iets zo snel en efficient mogelijk oplossen ;) ). Een totaal-oplossing is altijd beter dan een heleboel deel-oplossingen.

    Mijn methode is voor alle processoren, van alle types en alle merken, geschikt. Daarnaast kan deze methode ook in andere besturingssystemen dan Windows (bijv. Linux of BeOS) gebruikt worden. Handig voor OS-independent applications.

    // phaas
    QueryPerformanceCounter en QueryPerformanceFrequency zijn standaard API's die gebruikt kunnen worden om de frequentie en teller van de Performance teller uit te lezen. Zie de MSDN-library voor meer info (ook beschikbaar online: http://msdn.microsoft.com/library).
  • [quote:fb9f0c0956="Ben Lankamp"]// h4xX0r
    Die methode is eigenlijk niet goed, omdat je gebruik maakt van threads, en aangezien Windows met threads nogal eens allerlei onnodige rotzooi uitvoert, die ook processor-klikken kosten, kan je soms rare resultaten (zelfs op een Pentium, met name de oudere) krijgen. Daarnaast is deze methode, zoals je zelf al aangeeft, Intel-only. Het doet z'n werk wel goed op de nieuwere Pentiums (al kost het een stuk meer processorkracht, niet merkbaar maar 't gebeurt wel), maar is dus niet efficient en globaal genoeg (en dat is wat programmeren óók om draait: iets zo snel en efficient mogelijk oplossen ;) ). Een totaal-oplossing is altijd beter dan een heleboel deel-oplossingen.

    Mijn methode is voor alle processoren, van alle types en alle merken, geschikt. Daarnaast kan deze methode ook in andere besturingssystemen dan Windows (bijv. Linux of BeOS) gebruikt worden. Handig voor OS-independent applications.
    [/quote:fb9f0c0956]
    Wat een crap :lol:

    Het RDTSC commando [b:fb9f0c0956](die jij ook gebruikt)[/b:fb9f0c0956] is beschikbaar sinds de Pentium generatie processoren.

    Je zult daarom ook zien dat deze dan ook faalt op bijvoorbeeld een 80386/80486 type processor.

    Daarnaast werken we tegenwoordig met 'multitasking' operating systemen. Waarbij het OS zorgt voor het schedulen van de verschillende threads, waar je niet onderuit komt.

    Om een context-switch zo veel mogelijk te vermijden en dus het verlies van cpu cycles bij het klokken van de cpu speed wordt de thread prioriteit tijdelijk verhoogd.

    In de eerder vermelde code wordt dit niet afgevangen.

    Daarnaast zijn de QueryPerformance… API's Windows only, dus hoe je op 'OS-independent' komt is mij een raadsel.
    [quote:fb9f0c0956="Ben Lankamp"]

    // phaas
    QueryPerformanceCounter en QueryPerformanceFrequency zijn standaard API's die gebruikt kunnen worden om de frequentie en teller van de Performance teller uit te lezen. Zie de MSN-library voor meer info (ook beschikbaar online: http://msdn.microsoft.com/library).[/quote:fb9f0c0956]
    Waar denk je dat dit een wrapper van is?

    Als je dan toch deze API's gebruikt, kun je net zo goed meteen de processor snelheid uit het systeem uitlezen (ergens in de registry ofzo of m.b.v. WMI). Want Windows heeft dit al voor je opgezocht.

    [size=9:fb9f0c0956]– edit: typo's –[/size:fb9f0c0956]
  • Yep, zit wat in.
    Maar nu wil ik graag een code die wél OS-independent is ;-)
    Hoe zou je dat dan aan moeten pakken?

Beantwoord deze vraag

Dit is een gearchiveerde pagina. Antwoorden is niet meer mogelijk.