Обзор средств разработки высокопроизводительных приложений
Презентацию к данной лекции Вы можете скачать здесь.
8 способов достижения высокой производительности:
- Выбор вычислительной системы
- Выбор модели (если задача решается методом математического моделирования
- Использование эффективных вычислительных алгоритмов
- Использование приёмов написания оптимального кода
- Использование оптимизированных библиотек
- Оптимизация при компиляции
- Оптимизация готовой программы на основе анализа её выполнения
- Параллельное программирование
- параллелизм данных (OpenMP, Cilk Plus)
- параллелизм задач (MPI)
Эволюция вычислительных технологий
От фоннеймановской архитектуры к архитектуре параллельной
- Фоннеймановская архитектура
- Как эволюционировала архитектура вычислительных систем
- Эволюция программных технологий
Фоннеймановская архитектура последовательная, скалярная. В "классическом" фоннеймановском компьютере параллелизм отсутствует на всех уровнях.
Традиционная последовательная модель программирования, ориентированная на SISD архитектуры (по Флинну). Языки последовательного программирования.
Пользователю нужна производительность. Увеличение производительности позволяет:
- решать новые, более сложные задачи;
- решать старые задачи, но быстрее;
- решать старые задачи, но с более высокой точностью.
Многие расширения фоннеймановской архитектуры используют параллелизм на разном уровне
Вычислительные системы с распределённой памятью (кластеры, MIMD по классификации Флинна) от небольших кластеров до суперкомпьютеров, занимающих первые позиции в рейтинге Top 500 Supercomputers.
Кластер - группа вычислительных узлов, объединённых высокоскоростной коммуникационной подсистемой и представляющая с точки зрения пользователя единый аппаратный ресурс.
Программные инструменты разработки высокопроизводительных приложений
Низкоуровневые средства
Системные вызовы операционной системы (UNIX/Linux)
IPC (InterProcess Communications)
- именованные каналы;
- общая память;
- сообщения;
- семафоры.
IPC. Сообщения. Пример
Клиент
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include "mesg.h"
main()
{
message message;
key_t key;
int msgid, length, n;
if ((key = ftok("server", 'A')) < 0){
printf("Невозможно получить ключ\n"); exit(1); }
message.mtype=1L;
if ((msgid = msgget(key, PERM | IPC_CREAT)) < 0){
printf("Невозможно создать очередь\n"); exit(1); }
n = msgrcv(msgid, &message, sizeof(message), message.mtype, 0);
if (n > 0) {
if (write(1, message.buff, n) != n) {
printf("Ошибка вывода\n"); exit(1); }
}
else { printf("Ошибка чтения сообщения\n"); exit(1); }
exit(0);
Сервер
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include "mesg.h"
main()
{
Message message;
key_t key;
int msgid, length;
message.mtype = 1L;
if ((key = ftok("server", 'A')) < 0){
printf("Невозможно получить ключ\n"); exit(1); }
if ((msgid = msgget(key, 0)) < 0){
printf("Невозможно получить доступ к очереди\n"); exit(1); }
if ((length = sprintf(message.buff, "Здравствуй, Мир!\n")) < 0){
printf("Ошибка копирования в буфер\n"); exit(1); }
if (msgsnd(msgid, (void *) &message, length, 0) !=0){
printf("Ошибка записи сообщения в очередь\n");
exit(1); }
if (msgctl(msgid, IPC_RMID, 0) < 0){
printf("Ошибка удаления очереди\n"); exit(1); }
exit(0);



