Исследование влияния кэш-памяти (Лабораторная работа № 5). Измерение времени (Лабораторная работа № 1)

Страницы работы

Фрагмент текста работы

Лабораторная работа № 5

Исследование влияния кэш-памяти

Цель: исследовать влияние кэш-памяти на скорость обработки массивов различного размера.

       Кэш-память является промежуточным хранилищем данных между процессором и оперативной памятью. Она содержит копии наиболее часто используемых блоков данных. Размер кэш-памяти составляет от нескольких килобайт до нескольких мегабайт, а скорость доступа к ней в несколько раз превосходит скорость доступа к оперативной памяти, но уступает скорости обращения к регистрам.

Допустим, некоторая программа производит обработку элементов массива. Если построить график зависимости времени обработки массива от размера массива, то он не должен иметь линейный характер. В месте, соответствующем размеру кэш-памяти, на графике ожидается некоторый скачок. Таким образом мы и поступим. Напишем программу, которая последовательно увеличивает размер массива и производит над ним операции чтения и записи, а время, затраченное на эту обработку замеряет и записывает в файл.

//Подключаем библиотеки

#include <malloc.h>

#include <windows.h>

//Функция замера времени (ассемблерские вставки)

__int64 RTime()

{

      _asm _emit 0x0f

      _asm _emit 0x31

}

//Файлы вывода

FILE *rout,*wout,*rwout,*wrout;

//Константы К, размер блока и шаг

#define K 512

#define BLOCK_SIZE  (745*1024)

#define STEP_FACTOR (1*K)

//Основная процедура

int main()

{

//Проверяем на наличие выходных файлов

if ((rout = fopen("rres.txt", "w"))

    == NULL)

{

   perror("rres.txt");

   return 1;

}

if ((wout = fopen("wres.txt", "w"))

    == NULL)

{

   perror("qres.txt");

   return 1;

}

if ((rwout = fopen("rwres.txt", "w"))

    == NULL)

{

   perror("rwres.txt");

   return 1;

}

if ((wrout = fopen("wrres.txt", "w"))

    == NULL)

{

   perror("wrres.txt");

   return 1;

}

//Устанавливаем приоритет выполнения программы – критический (максимальный)

SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_TIME_CRITICAL);

//Результат

double res;

//Массив - вектор

int *matrix;

//Промежуточные переменные

int b,c,i;

float tmp=1;

float cash;

//Переменные результата времени – 64-битные целые числа

__int64 res1,res2;

double stmp=1;

//Выделяем память для вектора

matrix = (int*)malloc(BLOCK_SIZE);

//-----------------Чтение из КЭШа------------

//Начинаем перебирать блоки разного размера

for (b = 1*K; b < BLOCK_SIZE; b += STEP_FACTOR)

  {

      //Замеряем начальное время

      res1=RTime();

      //Цикл для увеличения времени выполнения

      for (i=0;i<12;i++) {

      //Пробегаем по всему блоку и читаем разные куски памяти

      for (c = 0; c <= b; c += sizeof(int)*4) {

      stmp += *(int*)((char *)matrix + c + 0);

      stmp += *(int*)((char *)matrix + c + 4);

      stmp += *(int*)((char *)matrix + c + 8);

      stmp += *(int*)((char *)matrix + c + 12);

      }

      }

      //Замеряем конечное время

      res2=RTime();

      //Вычисляем общее время работы

      res=res2-res1;

      //Считаем кэш в килобайтах

      cash=b;

      cash=cash/1024;

      //Выводим результат в файл

      fprintf(rout,"%f     %lf\n",cash, res);

  }

//----------------------Запись в Кэш  --------------------

//Опять же перебираем вектора разного размера

for (b = 1*K; b < BLOCK_SIZE; b += STEP_FACTOR)

  {

    res1=RTime();

for (i=0;i<12;i++)

{

      //Здесь мы просто записываем а не читаем данные из памяти

    for (c = 0; c <= b; c += sizeof(int)*4)

    {

      *(int*)((char *)matrix + c + 0) = tmp;

      *(int*)((char *)matrix + c + 4) = tmp;

      *(int*)((char *)matrix + c + 8) = tmp;

      *(int*)((char *)matrix + c + 12) = tmp;

    }

}

      res2=RTime();

      res=res2-res1;

      cash=b;

      cash=cash/1024;

    fprintf(wout,"%f     %lf\n",cash, res);

  }

//----------------Сначала чтение, потом запись ----------

  for (b = 1*K; b < BLOCK_SIZE; b += STEP_FACTOR)

  {

    res1=RTime();

for (i=0;i<12;i++)

{

    for (c = 0; c <= b; c += sizeof(int)*2)

    {

      stmp += *(int*)((char *)matrix + c + 0);

      stmp += *(int*)((char *)matrix + c + 4);

      *(int*)((char *)matrix + c + 0) = tmp;

      *(int*)((char *)matrix + c + 4) = tmp;

    }

}

    res2=RTime();

      res=res2-res1;

      cash=b;

      cash=cash/1024;

    fprintf(rwout,"%f     %lf\n",cash, res);

  }

//-----------------------Сначала запись, потом чтение -----------

  for (b = 1*K; b < BLOCK_SIZE; b += STEP_FACTOR)

Похожие материалы

Информация о работе