Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

[ООП] / Лекции / Zao_2009_Paral_2

.doc
Скачиваний:
20
Добавлен:
07.02.2016
Размер:
40.45 Кб
Скачать

3

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

Использование класса TThread для имитации параллельных и векторных ЭВМ

Цель: Научиться создавать параллельные и векторные алгоритмы решения задач, используя класс TThread в инструментальной среде программирования Borland C++ Builder.

Задание 1. Имитация параллельной ЭВМ

Создать с помощью Borland C++ Builder консольное приложение, в котором вычисляются значения функции y=sin(x)+cos(x) при изменении независимой переменной x в диапазоне от 0 до 360 с дискретностью 1. Функции c=cos(x) и s=sin(x) должны вычисляться в двух независимых дочерних потоках, порожденных основным потоком программы, а вычисление их суммы и вывод результата на печать ‑ в основном потоке.

Порядок выполнения Задания 1

  1. Создайте новый проект консольного приложения;

  2. Этот проект будет состоять из основного модуля (с телом функции main()) и модулей, содержащих описания и определения классов, которые порождены от TThread. Поэтому необходимо описать массив x таким образом, чтобы он был доступен во всех модулях (т.е. был глобальным). Для этого создайте новый модуль (File|New Unit) и поместите в нем определение массива x (float x[360];). В заголовочном файле этого модуля объявите переменную x внешней (extern float x[360];);

  3. Создайте класс потока, который вычисляет функцию cos(x) во всех точках массива x. Для этого выберите в репозитории (File|New вкладка New Items) объект Thread Object и в появившемся диалоговом окне введите название нового класса потока (TCosThread). Этот класс должен в функции-члене Execute() содержать код вычисления массива значений функции с=cos(x). Необходимый для этого массив с[] лучше всего объявить членом класса, поэтому в заголовочном файле объявления класса в секции public: следует описать ее как float c[360];

  4. Аналогично п.3 создайте модуль для класса потока TSinThread, вычисляющего s=sin(x);

  5. Создайте отдельную папку для проекта и сохраните все файлы проекта. Это необходимо, чтобы файлы модулей получили свои имена. Следите за тем, чтобы все файлы проекта были вместе в одной папке;

  6. При помощи директивы #include включите имена заголовочных файлов, содержащих описания переменной x во все модули (*.срр), а также включите заголовочные файлы модулей с классами в главный модуль проекта.

  7. В функции main() главного модуля необходимо создать указатели на экземпляры классов TcosThread и TSinThread. Перед запуском дочерних потоков инициализируйте массив x[] значениями точек диапазона (в радианах, константа  описана в файле <math.h> как M_PI). Запуск потоков производится при помощи вызова конструкторов при создании экземпляров классов TCosThread и TSinThread с параметром false (см. указания к предыдущей лабораторной работе). Перед обработкой результатов в главном потоке необходимо дождаться завершения каждого из потоков вызовом метода WaitFor() для каждого экземпляра потока. После завершения потоков произведите в цикле суммирование членов c[] и s[] и вывод полученных результатов. В конце программы вызовите деструктор Free() для каждого экземпляра потока.

  8. Сохраните, скомпилируйте и запустите на выполнение приложение.

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

Первый вариант. Разработать приложение, в котором с помощью потоков реализуется параллельный алгоритм для вычисления функции tg(x)=x+x3/3+2x5/15+17x7/315+62x9/2855 в 45 точках, равномерно распределенных в диапазоне (0,45/180], причем второе, третье, четвертое и пятое слагаемые должны вычисляться соответственно в первом, втором, третьем и четвертом дочерних потоках, а окончательное вычисление функции – в основном потоке. Тексты функции main() и метода Execute() приведите в отчете.

Второй вариант. Разработать приложение, в котором с помощью потоков реализуется параллельный алгоритм для вычисления функции ctg(x)=1/x‑x/3‑x3/45‑2x5/945‑x7/4725 в 45 точках, равномерно распределенных в диапазоне (0,45/180], причем третье, четвертое и пятое слагаемые должны вычисляться соответственно в первом, втором и третьем дочерних потоках, а окончательное вычисление функции – в основном потоке. Тексты функции main() и метода Execute() приведите в отчете.

Задание 2. Имитация векторного процессора

Создать с помощью Borland C++ Builder консольное приложение, которое имитирует работу векторного процессора для вычисления векторной функции y=sin(x)+cos(x). Длина векторов x и y равна 36. Компонентами вектора x являются точки круга: x = (0, 10, 20,…,350). Секции векторного процессора имитировать с помощью потоков. Для этого в приложении создать 36 дочерних потоков, а подготовку входного вектора x и формирование выходного вектора y осуществить в основном потоке.

Порядок выполнения Задания 2

  1. Создайте новую папку для приложения;

  2. Создайте новое консольное приложение и определите в главной функции main() переменные: параметр цикла i, результирующий вектор float y[36], вспомогательные переменные (при необходимости);

  3. Создайте класс потока и присвойте ему имя (например, VectorComponent).

  4. В заголовочном файле, где объявляется класс, в секции private: опишите переменную-член класса float alfa, а в секции public: переменную-член класса float value и скорректируйте объявление и определение конструктора класса, введя в список его аргументов дополнительный элемент для инициализации внутренней переменной alfa:

__fastcall VectorComponent(float angle, bool CreateSuspended)

{alfa=angle;}

  1. Скорректируйте определение метода класса Execute(), добавив в него код для вычисления компонентов вектора: value=sin(alfa)+cos(alfa);

  2. В главной функции приложения main() объявите массив указателей на объекты типа VectorComponent (например, VectorComponent *Component[36]). Сформируйте значения компонентов вектора x и, используя операцию new для динамического распределения памяти, создайте массив экземпляров класса VectorComponent, инициализировав их внутренние члены-данные alfa значениями компонентов вектора x, а параметр CreateSuspended ‑ значением false. Для ожидания завершения работы потоков примените метод WaitFor(). Присвойте компонентам вектора y значения value, освободите память методом Free() и распечатайте результирующий вектор y;

  3. Сохраните, скомпилируйте и запустите приложение.

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

Первый вариант. Разработать приложение, в котором с помощью потоков реализуется векторный алгоритм для вычисления функции ctg(x)=1/x‑x/3‑x3/45‑2x5/945‑x7/4725 в 45 точках, равномерно распределенных в диапазоне (0,45/180]. Вычисления для всех точек должны выполняться параллельно. Тексты функции main() и метода Execute() приведите в отчете.

Второй вариант. Разработать приложение, в котором с помощью потоков реализуется векторный алгоритм для вычисления функции tg(x)=x+x3/3+2x5/15+17x7/315+62x9/2855 в 45 точках, равномерно распределенных в диапазоне (0,45/180]. Вычисления для всех точек должны выполняться параллельно. Тексты функции main() и метода Execute() приведите в отчете.

Контрольные вопросы

  1. В чем отличие между параллельным и векторным процессорами?

  2. Приведите определение степени параллелизма алгоритма и зависит ли она от архитектуры процессоров?

  3. Изобразите в виде блок-схем алгоритмы заданий 1 и 2;

  4. Приведите определение ускорения параллельного алгоритма;

  5. Запишите формулу закона Амдаля. Приведите пример расчета ускорения алгоритма, если 0,5% вычислений по нему выполняется на одном процессоре (последовательно), а остальные ‑ параллельно на 50 процессорах.

Параллельное программирование

Соседние файлы в папке Лекции