Navigointi
Etusivu
PhpSysInfo
~sami/
Blogi
vnstat
Ladattavaa
Virityksiä
Muuta
Linkkejä
Monsujen tappopeli
Vieraskirja
Chat
|
|
Prosessorin välimuistitesteri
Tämä ohjelma testaa muistin kaistanleveyttä eri datamäärillä. Pienempien määrien kopiointi on nopeampaa, koska
kopioitava data löytyy jo valmiiksi prosessorin välimuistista. Ensimmäiset hidastumiset ilmenevät prosessorin
joutuessa hakemaan dataa seuraavan tason (L2, L3) välimuisteista, ja sitä seuraava hidastuminen ilmenee välimuistien
käydessä liian pieneksi, jolloin dataa joudutaan hakemaan muistiväylän yli varsinaisesta RAM-muistista. Jossain
vaiheessa kopiointi alkaa kestämään sen verran pitkään, että käyttöjärjestelmän ytimen vuoronnin alkaa katkoa
ohjelman suoritusta. Hitaammilla koneilla tämä saattaa tapahtua jo ennen kuin välimuistien rajat tulevat vastaan.
Koodi kääntyy GCC:llä ja useimmilla POSIX-yhteensopivilla kääntäjillä useimmilla POSIX-yhteensopivilla
käyttöjärjestelmillä toimivaksi ohjelmaksi.
Tämä ei ole varsinaisesti benchmark-ohjelma, eikä tämä näytä muistin maksimaalista kaistanleveyttä.
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <string.h>
#include <sys/time.h>
#define REPEATS 100
int do_test(unsigned kb, unsigned *us) { unsigned bytes = kb << 10; char *buff0 = malloc(bytes); char *buff1 = malloc(bytes); char *buff2 = malloc(bytes); unsigned n; suseconds_t usec; time_t sec; struct timeval tv;
if(!buff0 || !buff1 || !buff2) return -1;
// fill buff0 with something for(n=bytes;n--;) buff0[n] = rand();
memcpy(buff1, buff0, bytes);
gettimeofday(&tv, 0); usec = tv.tv_usec; sec = tv.tv_sec;
for(n=REPEATS;n--;) { memcpy(buff2, buff1, bytes); memcpy(buff1, buff2, bytes); }
gettimeofday(&tv, 0); if(tv.tv_sec != sec) *us = (tv.tv_sec - sec) * 1000000; else *us = 0; *us += tv.tv_usec - usec;
if(memcmp(buff0, buff1, bytes)) return 1;
free(buff0); free(buff1); free(buff2); return 0; }
int main() { unsigned kb = 1; unsigned result; int rc; unsigned mbps = 0; unsigned cache = 1;
srand(time(0));
while(kb < 0x80000) { printf("Copying %u kilobytes %u times... ", kb, REPEATS<<1); if(rc = do_test(kb, &result)) { switch(rc) { case -1: puts("Out of memory"); return 1; case 1: puts("Memory error"); return 1; } } if(mbps && (((kb*REPEATS)<<11) / result) < mbps - (mbps >> 2)) printf("%u. slowdown detected, ", cache++); mbps = ((kb*REPEATS)<<11) / result;
printf("done in %u.%.6u s (%u MB/s)\n", result/1000000, result%1000000, mbps); kb<<=1; } }
|