内存延时测试

2019-10-11  本文已影响0人  yanfeizhang
#include <stdlib.h>
#include <stdio.h>
#include "clock.h" /* routines to access the cycle counter */

#define MINBYTES (1 << 11)  /* Working set size ranges from 2 KB */
#define MAXBYTES (1 << 26)  /* ... up to 64 MB */
#define MAXSTRIDE 64        /* Strides range from 1 to 64 elems */
#define MAXELEMS MAXBYTES/sizeof(double) 

#define ASIZE (1 << 17)

double data[MAXELEMS];      /* The global array we'll be traversing */

/* start declare functions */
void init_data(double *data, int n);
void run_delay_testing();
double get_seque_access_result(int size, int stride, int type);
double get_random_access_result(int size, int type);
/* end declare functions */


int main()
{       
    init_data(data, MAXELEMS);  
    
    printf("Delay  (ns)\n");    
    run_delay_testing();
    printf("\n\n");
    
    exit(0);
}

void run_delay_testing(){   
    int size;        /* Working set size (in bytes) */
    int stride;      /* Stride (in array elements) */
    
    /*Print the size header */
    printf("\t");
    for (size = MAXBYTES; size >= MINBYTES; size >>= 1) {
        if (size > (1 << 20)){
            printf("%dm\t", size / (1 << 20));
        }else{
            printf("%dk\t", size / 1024);
        }
    }
    printf("\n");   

    /* estmate the band width sequencely */
    for (stride = 1; stride <= MAXSTRIDE; stride=stride+1) {
        printf("s%d\t", stride);        
        for (size = MAXBYTES; size >= MINBYTES; size >>= 1) {   
            printf("%.2f\t", get_seque_access_result(size, stride, 1));
        }
        printf("\n");
    }
    
    /*  estmate the band width real randomly*/
    printf("\random\t");
    for (size = MAXBYTES; size >= MINBYTES; size >>= 1) {       
        printf("%.2f\t", get_random_access_result(size,1));
    }
    printf("\n");
}

/* $end mountainmain */

/* init_data - initializes the array */
void init_data(double *data, int n)
{
    int i;

    for (i = 0; i < n; i++)
    data[i] = i;
}

void create_rand_array(int max, int count, int* pArr)
{
    int i;
    for (i = 0; i < count; i ++,pArr++) {
        int rd = rand();        
        int randRet = (long int)rd * max / RAND_MAX;
        *pArr = randRet;
    }
    return;
}



/*
 * seque_access 
 *      - access global data array step by step 
 */
void seque_access(int elems, int stride) /* The test function */
{
    int i;
    double result = 0.0; 
    volatile double sink; 

    for (i = 0; i < elems; i += stride) {
    result += data[i];  
    }
    sink = result; /* So compiler doesn't optimize away the loop */
}


/*
 * random_access 
 *      - access global by random way indexed by random_index_arr 
 */
void random_access(int* random_index_arr, int count) /* The test function */
{ 
    int i;
    double result = 0.0; 
    volatile double sink; 

    for (i = 0; i < count; i++) {
        result += data[*(random_index_arr+i)];  
    }
    sink = result; /* So compiler doesn't optimize away the loop */
}


/*
 * get_random_access_result : test the computer storage(register,cache or memory) band width. 
 *      - size: data size will be tested
 *      - stride: steps
 *      - type: 0 get the band width, 
 *      -       1 get the consumed cpu cycles per operation.
 */
double get_seque_access_result(int size, int stride, int type)
{   
    int i;  
    long int operations;
    long int total_accessed_bytes;
    long int used_microseconds;
    
    int samples = 1000;     
    int elems = size / sizeof(double); 
            
    /* run the test*/
    start_timer();
    for(i=0; i<samples; i++){
        seque_access(elems, stride);
    }
    used_microseconds = get_timer();
    if(0==used_microseconds){
        return 0;
    }
    
    /* analysize result*/
    operations = (long int)samples * (long int)elems / stride;  
    total_accessed_bytes = operations * sizeof(double);

    
    double result = 0;
    if(0==type){ /* get width */
    
        /* width    = size(M)/ time(s) 
                    = (total_accessed_bytes / 1000000) / (used / 1000000000) 
                    = total_accessed_bytes*1000/used_microseconds;
        */  
        result = total_accessed_bytes * 1000  / used_microseconds;
        
    }else if(1==type){/* get cycles_per_operation */        
        result = (double)used_microseconds/operations; 
    }   
    
    return result;
}
    
/*
 * get_random_access_result : test the computer storage(register,cache or memory) band width. 
 *      - size: data size will be tested
 *      - type: 0 get the band width, 
 *      -       1 get the consumed cpu cycles per operation.
 */
double get_random_access_result(int size, int type)
{   
    int i;
    int *p;
    
    long int operations;
    long int total_accessed_bytes;
    long int used_microseconds;
    
    int samples = 300;      
    int elems = size / sizeof(double); 
    int access_count = elems;
    
    /* prepare for random access*/
    int* random_access_arr = malloc(access_count*sizeof(int));  
    for(i=0,p=random_access_arr; i<access_count; i++,p++){
        *p = 0;
    }   
    create_rand_array(elems, access_count, random_access_arr);  
    
        
    /* run the test*/
    start_timer();
    for(i=0; i<samples; i++){
        random_access(random_access_arr, access_count);
    }
    used_microseconds = get_timer();
    
    /* analysize result*/
    operations = (long int)samples * (long int)access_count;    
    total_accessed_bytes = operations * sizeof(double);

    
    double result = 0;;
    if(0==type){ /* get width */
    
        /* width    = size(M)/ time(s) 
                    = (total_accessed_bytes / 1000000) / (used / 1000000000) 
                    = total_accessed_bytes*1000/used_microseconds;
        */  
        result = total_accessed_bytes * 1000  / used_microseconds;
        
    }else if(1==type){/* get cycles_per_operation */        
        result = used_microseconds/operations*2.4; 
    }   
    
    return result;
}
/* $end mountainfuns */
上一篇 下一篇

猜你喜欢

热点阅读