Министерство Образования Российской Федерации
Новосибирский Государственный Технический Университет
Лабораторные работы
По дисциплине: Архитектура ЭВМ и ВС
Выполнил: студент ПМ-22
Савлюк В.И.
Проверила:
Маркова В.П.
Новосибирск
2003
Программирование нижеследующих задач производилось с учетом архитектуры процессора и в частности кэш-памяти. Тестирование производилось на Intel P-Celeron 1100A(0.13мк).
Замеры производились после компиляции программ компилятором ‘gcc’ с ключом –О3 (полная оптимизация по времени) под управлением ОС Linux Redhat 7.3 в чистом консольном режиме с наивысшим приоритетом.
Задача. Определить максимальное число локальных переменных, которое может полностью проецироваться на регистры общего назначения.
Задание. Построить тестовую программу для решения поставленной задачи. По результатам работы программы построить таблицу или график в осях X-число локальных переменных, Y-время доступа к ним. На основании анализа таблицы или графика сделать выводы о числе доступных для подпрограмм тестовой программы регистров. Сверить полученный результат с приведенным в документации при ее наличии.
Решение.
Для решения поставленной задачи напишем программу, которая будет последовательно обращаться к некоторому количеству переменных. Если все эти переменные смогут занять свободные регистры процессора, то время доступа к ним будет минимальным, иначе время доступа возрастет. Каждый раз увеличивая на 1 число переменных, найдем такое n, начиная с которого время доступа к переменным увеличиться с некоторым скачком. Так как время доступа к одной переменной ничтожно мало и не поддается замерам программными средствами, будем сравнивать время многократного доступа к переменным. Кроме того, учтем, что процессор технологии Intel Celeron A позволяет работать с группой регистров, как с массивом.
Листинг 1.
#include <stdio.h>
#include <sys/timeb.h>
void main() {
FILE * out = fopen("local.csv","wt");
int * a = new int[50];
timeb start, end;
int i,j,n;
long int measured =0;
for(n=1;n<50;n++) {
for(i=0;i<n;i++) a[i]=0;
ftime(&start);
for(i=0;i<10000000;i++) {
for(j=0;j<n;j++) a[j]++;
for(j=0;j<n;j++) a[j]++;
for(j=0;j<n;j++) a[j]++;
for(j=0;j<n;j++) a[j]++;
for(j=0;j<n;j++) a[j]++;
for(j=0;j<n;j++) a[j]++;
for(j=0;j<n;j++) a[j]++;
for(j=0;j<n;j++) a[j]++;
for(j=0;j<n;j++) a[j]++;
for(j=0;j<n;j++) a[j]++;
}
ftime(&end);
measured=(end.time*1000+end.millitm)-(start.time*1000+ start.millitm);
fprintf(out,"%i;%i\n",n,measured);
printf("Measured: %i - %i\n",n,measured);
}
fclose(out);
}
Т.е. наша программа открывает файл local.csv и сливает в него результаты замеров времени в формате “a;b”, где а - число локальных переменных, b-время затраченное на 100 млн. обращений к ним в миллисекундах. Программа сохраняет файл в формате csv с соответствующим форматом данных для более удобной обработки данных в пакете для работы с таблицами и графиками (в данном случае MSExcel). Анализируя результаты работы программы можно построить такой график.
График1. Время доступа к локальным переменным.
График2. Среднее время доступа к одной переменной.
Итак, мы явно увидели, что в процессе перехода от 5 переменных к 6 наблюдается значительный скачок времени доступа. Следовательно, программе реально доступно 5 регистров процессора.
Задача. Определить максимальный размер массива, целиком умещающегося в кэше, в оперативной памяти.
Задание. Построить тестовую программу для решения поставленной задачи. По результатам работы программы построить графики в осях X-размер блока памяти, Y-время доступа. На основании анализа графиков сделать выводы о размере доступных для тестовой программы размерах кэша и оперативной памяти.
Решение. Тестирование заключается в следующем. Мы выделяем определенный блок памяти размера N и замеряем время доступа к нему. В данном случае мы определяем массив некоторого размера и осуществляем доступ ко всем его переменным. В случае, если массив целиком умещается в кэш-память, время доступа к нему будет минимально, как только он перестает там умещаться, наблюдается резкий скачок во времени доступа.
Листинг 2.
#include <stdio.h>
#include <sys/timeb.h>
#include <stdlib.h>
void main() {
FILE * out = fopen("mem.csv","wt");
timeb start, end;
int S = 1024*1024;
void * ptr = malloc(S);
unsigned char * p = (unsigned char*)ptr;
int i,times;
long int measured=0;
for(int size = 0;size<=S;size+=512) {
ftime(&start);
for(i = 0; i < size; i++) {
p[i] = 0;
}
for(times = 0;times<1000;times++) {
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.