Avatar billede mickni33 Nybegynder
19. december 2005 - 15:26 Der er 9 kommentarer og
2 løsninger

cache memory

Jeg skal lave et program som kan finde ud af hvike levels af cache memory jeg har på computeren....
Men hvordan gør jeg egentlig det?
måske med nogle links.
Avatar billede driis Nybegynder
19. december 2005 - 16:38 #1
Du kan bruge CPUID instruktionen, det kræver at du laver en smule inline assembler. Desværre er det lidt noget bøvl, da AMD og Intel har lidt forskellige måder at returnere data. Derfor skal der en smule forskelligt kode til alt efter hvilken processor, koden aktuelt køres på.

Da jeg har en AMD, kunne jeg lave det følgende eksempel. Det burde være nemt nok at få til at virke på Intel, du skal bare have fat i deres instruktions-dokumentation og hitte ud af hvilken parameter der skal sendes med i EAX, og hvor data bliver returneret.
Avatar billede driis Nybegynder
19. december 2005 - 16:38 #2
#include <stdio.h>
#include <windows.h>

#define AMD_EXTENDED 0x80000000

void CPUID(int param, unsigned long *regsout)
{
    unsigned long regs[4];
    __asm
    {
        push eax;
        push ebx;
        push ecx;
        push edx;

        mov eax    ,param;
        cpuid;
        mov dword ptr[regs],eax;
        mov dword ptr[regs + 4],ebx;
        mov dword ptr[regs + 8],ecx;
        mov dword ptr[regs +12],edx;
       
        pop edx;
        pop ecx;
        pop ebx;
        pop eax;
    }

    memcpy(regsout,regs,16);
}

int main()
{
    unsigned long support = 0;
    unsigned long l2 = 0;
    unsigned long l1i = 0;
    unsigned long l1d = 0;
    unsigned long regs[4] = {0};
    char vendor[13] = {0};
   
    CPUID(0,regs);
    support = regs[0];
    regs[0] = regs[3];
    regs[3] = regs[2];
    regs[2] = regs[0];
    memcpy(vendor, regs + 1,12);   
    printf("CPU vendor: %s\n", vendor);

    if ( strcmp(vendor,"AuthenticAMD") == 0 )
    {
        CPUID(AMD_EXTENDED,regs);
        if ( regs[0] >= 6 )
        {
            CPUID(AMD_EXTENDED | 5,regs);
            l1d = regs[2] >> 24;
            l1i = regs[3] >> 24;
            CPUID(AMD_EXTENDED | 6,regs);
            l2 = regs[2] >> 16;

            printf("L1 Cache (data)\t\t: %d\nL1 Cache (instruction)\t: %d\n",l1d,l1i);
            printf("L2 Cache\t\t: %d\n",l2);
        }
    }
    return 0;
}
Avatar billede driis Nybegynder
19. december 2005 - 16:39 #3
( hvis du ikke bruger MS' compiler skal __asm nok ændres til asm )
Avatar billede mickni33 Nybegynder
19. december 2005 - 16:40 #4
hehe jeg har AMD
og Borland kan vel nok klare den, eller hva
Avatar billede mickni33 Nybegynder
19. december 2005 - 16:41 #5
hmmm kan du sætte nogle kommentar de vigtigste steder :-(
Avatar billede driis Nybegynder
19. december 2005 - 16:47 #6
"cpuid" er en instruktion som findes på både AMD og Intel. Når den køres, returnerer den information om processoren i registrene eax, ebx, ecx, edx. Hvad der returneres afhænger af indholdet i eax før den kaldes. Når vi kommer til at hente cache størrelsen ud, bruger AMD og Intel desværre forskellige parametre; for Intel er parameteren 2 og for AMD er den 0x8000005 og -6 hhv. Intel returnerer sikkert også tallene andre steder i registrene, så der skal laves en alternativ version af ovenstående for at tage højde for Intel processorer.

Det der nok er mest interessant er CPUID funktionen:
void CPUID(int param, unsigned long *regsout)
{
    unsigned long regs[4];
    __asm  // Kode heri er assembler kode
    {
        // push registre på stakken, da compileren forventer at de forbliver uændrede
        push eax;
        push ebx;
        push ecx;
        push edx;

        // flyt parameter til eax
        mov eax    ,param;
        // kør cpuid instruktionen
        cpuid;
        // kopier data til output array
        mov dword ptr[regs],eax;
        mov dword ptr[regs + 4],ebx;
        mov dword ptr[regs + 8],ecx;
        mov dword ptr[regs +12],edx;
     
        // ryd op, gendan registerværdier
        pop edx;
        pop ecx;
        pop ebx;
        pop eax;
    }

    // kopier til endelig output array 
    memcpy(regsout,regs,16);
}
Avatar billede mickni33 Nybegynder
19. december 2005 - 16:54 #7
hvad betyder det der l du har skrevet foran
    unsigned long l2 = 0;
    unsigned long l1i = 0;
    unsigned long l1d = 0;
Avatar billede driis Nybegynder
19. december 2005 - 17:16 #8
"l2","l1i","l1d", er blot variabelnavne. Det der sker i main() er stort set bare, at vi kalder CPUID med de rigtige parametre, som jeg har slået op i AMD's dokumentation. Og dernæst noget datagymnastik for at få vist værdierne på en pæn måde.

http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/25481.pdf
Avatar billede mickni33 Nybegynder
19. december 2005 - 17:19 #9
hehe nååå ok :-)
Level 1 data
Level 2
Level 1i  ??? hvad er i
Avatar billede driis Nybegynder
19. december 2005 - 17:20 #10
Level 1 instruction cache. Hvis du har 128 kb L1 cache, er de (i hvert fald på AMD) delt i 64 kb til instruktioner og 64 kb til data.
Avatar billede arne_v Ekspert
19. december 2005 - 23:48 #11
hvis ikke det var fordi at WMI i C++ er så besværligt at bruge som det er, så var
det jo nok et pænere alternativ
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester



IT-JOB