Определение числа регистров, доступных для локальных переменных подпрограммы. Определение размеров реально доступной для программы памяти

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

Содержание работы

Задания для самостоятельного программирования

1.  Определение числа регистров, доступных для локальных переменных подпрограммы

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

Задача. Определить максимальное число локальных переменных, которое может полностью проецироваться на регистры общего назначения.

Задание. Построить тестовую программу для решения поставленной задачи. По результатам работы программы построить таблицу или график в осях X-число локальных переменных, Y-время доступа к ним. На основании анализа таблицы или графика сделать выводы о числе доступных для подпрограмм тестовой программы регистров. Сверить полученный результат с приведенным в документации при ее наличии.

Пример решения для платформы на базе процессора Alpha 21264. Для решения задачи будем пользоваться измерением времени обращения к группе локальных переменных для возрастающего числа локальных переменных. Так как время однократного обращения ко всем переменным гораздо меньше разрешающей способности используемого для измерения таймера, будем производить доступ к переменным большое количество раз. Кроме этого, учтем, что система команд Alpha 21264 позволяет работать с группой регистров как с массивом.

Текст 1. Программ измерения времени доступа к локальным переменным для Alpha 21264:

#include <stdio.h>

#include <sys/time.h>

#include <unistd.h>

struct timeval      tv1, tv2, dtv;

struct timezone    tz;

void benchmark_start(void){         

              gettimeofday(&tv1, &tz);

}

long benchmark_stop(void){

              gettimeofday(&tv2, &tz);

              dtv.tv_sec            = tv2.tv_sec - tv1.tv_sec;

              dtv.tv_usec          = tv2.tv_usec - tv1.tv_usec;

              if(dtv.tv_usec < 0){

                             dtv.tv_sec--;

                             dtv.tv_usec += 1000000;

              }

              return dtv.tv_sec * 1000 + dtv.tv_usec / 1000;

}

int i, j;

void subr1()

{

        int params[SIZE];

        for(j = 0; j < SIZE; j++)

            params[j] = 0;

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

    {

        for(j = 0; j < SIZE; j++)

            params[j]++;

        for(j = 0; j < SIZE; j++)

            params[j]++;

        for(j = 0; j < SIZE; j++)

            params[j]++;

        for(j = 0; j < SIZE; j++)

            params[j]++;

        for(j = 0; j < SIZE; j++)

            params[j]++;

        for(j = 0; j < SIZE; j++)

            params[j]++;

        for(j = 0; j < SIZE; j++)

            params[j]++;

        for(j = 0; j < SIZE; j++)

            params[j]++;

        for(j = 0; j < SIZE; j++)

            params[j]++;

        for(j = 0; j < SIZE; j++)

            params[j]++;

    }

}

main()

{

        int res;

        benchmark_start();

        subr1();

        res = benchmark_stop();

        printf("%d (msec.)\n", res);

        printf("%d ()\n", res / SIZE);

}

2.  Определение размеров реально доступной для программы памяти

Хотя размеры кэша и оперативной памяти обычно можно найти в документации, они не всегда соответствуют реально доступным для программ размерам. Причина этого – в том, что кроме программы пользователя этими же кэшем и памятью пользуются операционная система и другие программы.

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

Задание. Построить тестовую программу для решения поставленной задачи. По результатам работы программы построить графики в осях X-размер блока памяти, Y-время доступа. На основании анализа графиков сделать выводы о размере доступных для тестовой программы размерах кэша и оперативной памяти.

Пример решения задачи для Intel P-III 850. Идея теста – последовательно выделять блоки памяти с возрастающим размером и замерять время многократного последовательного доступа ко всем ячейкам выделенного блока. Пока блок полностью умещается в определенном уровне иерерхии памяти, зависимость времени от размера блока растет линейно. Скачки между линейными участками определяют размеры блоков, которые перестают умещаться в определенном уровне памяти.

Текст 2. Программа измерения времени последовательного обращения к ячейкам блока памяти для Intel P-III 850:

#include <stdio.h>

#include <stdlib.h>

#include <sys/time.h>

#include <unistd.h>

struct timeval      tv1, tv2, dtv;

struct timezone    tz;

void benchmark_start(void); // см. реализацию в тексте 1

long benchmark_stop(void); // см. реализацию в тексте 1

int TIMES;

int test(void *ptr, int _size)

{

              int i, times, size;

              int *p;

              p = (int*)ptr;

              size = _size / sizeof(int);

              benchmark_start();

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

                             p[i] = 0;

              for(times = 0; times < TIMES; times++)

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

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