Можно ли запустить программу SIMD на современных процессорах семейства x86

x86 — архитектура процессора c одноимённым набором команд, впервые реализованная в процессорах компании Intel.Название образовано от двух цифр, которыми заканчивались названия процессоров Intel ранних моделей: 8086, 80186, 80286 (i286), 80386 (i386),80486 (i486). За время своего существования набор команд постоянно расширялся, сохраняя совместимость с предыдущими поколениями.

Для организации групповой обработки данных в процессорах используется SIMD расширения к х86 инструкциям. Аббревиатура SIMD расшифровывается как Single Instruction Multiple Data (одна инструкция – множество данных). Под SIMD расширением понимается программно-аппартное решение, представляющее собой совокупность дополнительных регистров и наборов инструкций процессора, предназначенных для групповой обработки данных. Также необходимо наличие соответствующих компиляторов, ”знающих” SIMD инструкции и способных оптимизировать под них код. Быстродействие повышается за счет того, что каждая команда из дополнительного набора выполняет действие, для которого понадобилось бы несколько команд основного набора. Оптимизированная программа, как правило, может работать на процессорах как с поддержкой необходимых инструкций (повышенное быстродействие), так и с отсутствием оных. Однако на практике встречаются программы, которые отказываются работать при отсутствии у процессора определенного набора SIMD инструкций. Такая проблема может возникнуть на старых процессорах, при использовании современных программ.

Однако такие исключения встречаются редко и в большинстве случаeв программа, взамен отсутствующих SIMD, будет использовать универсальные (generic) х86 инструкции. При этом мы не получим никакого повышения быстродействия, но и снижения производительности (по сравнению с обычным кодом) также не будет

Пользовательские типы данных. Тип MPI_type_contiguous. Примеры.

MPI разрешает пользователю во время выполнения создавать собственные типы данных MPI. Чтобы построить тип данных для MPI, необходимо определить расположение данных в типе: тип элементов и их относительные местоположения в памяти. Такой тип называют производным типом данных.

Самый простой конструктор типа MPI_Type_contiguous создает новый тип, элементы которого состоят из указанного числа элементов базового типа, занимающих смежные области памяти.

int MPI_Type_contiguous(int count, MPI_Datatype oldtype, MPI_Datatype *newtype)

count – число элементов базового типа; oldtype – базовый тип данных; newtype – новый производный тип данных.

Пусть oldtype имеет карту typemap { ( double, 0), (char, 8) } с длиной 16 и пусть count = 3. Карта нового типа будет: { (double, 0), (char, 8), (double, 16), (char, 24), (double, 32), (char, 40) }; то есть содержать меняющиеся удвоенные значения и символьные элементы со смещением 0, 8, 16, 24, 32, 40.

Напишите программу параллельного поиска минимального числа в массиве.

int main(int argc,char **argv)

{

int size,rank,i,n=12;

float a[]={10.0,-1.0,2.0,3.0,7.0,6.0,3.0,1.0,-2.0,4.0,-9.0,20.0};

MPI_Status status;

MPI_Init(&argc,&argv);

MPI_Comm_rank(MPI_COMM_WORLD,&rank);

MPI_Comm_size(MPI_COMM_WORLD,&size);

float f=0,min=0,mini=0;

int nachalo,konec,shag;

shag=n/(size-1);

if(rank!=size-1)

{

nachalo=rank*shag;

konec=rank*shag+shag;

min=a[nachalo];

for(i=nachalo;i<konec;i++)

if(a[i]<min)

min=a[i];

MPI_Send(&min,1,MPI_FLOAT,size-1,1,MPI_COMM_WORLD);

}

if(rank==size-1){

mini=32000;

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

{ MPI_Recv(&min,1,MPI_FLOAT,i,1,MPI_COMM_WORLD,&status);

if(mini>min)

mini=min; }

printf("%f\n",mini);

}

MPI_Finalize();}

Сурак

1.В каких случаях эффективно использование параллельных методик программирования ?

В последнее время, чтобы получить возможность задействовать на практике ту дополнительную вычислительную мощность, стало необходимо задействовать параллельные вычисления. Сейчас по разным причинам производители процессоров предпочитают многоядерные архитектуры, и для получения всей выгоды от возросшей производительности ЦП программы должны переписываться в соответствующей манере. В итоге происходит неуклонное возрастание потребности в ресурсоемких расчетах, которые в ряде случаев можно выполнить только на базе высокопроизводительной техники с помощью методов параллельных вычислений. Параллельные вычисления применяются в:

1) системах поддержки проектирования (CAD – Computer Aided Design). В таких системах необходимость осуществлять моделирование в реальном масштабе времени предъявляет высокие требования к производительности программного обеспечения. 2) инженерных приложениях. К этому классу относятся разнообразные задачи из области прочностного моделирования, моделирование аварийных ситуаций и многие другие; 3) математическом моделировании физических процессов. В этот широкий класс входят задачи динамики жидкости и газа, электромагнитные и ядерные взаимодействия, процессы горения и т.п. Такие процессы, как правило, описываются системами уравнений в частных производных. 4) моделирование глобальных процессов в науках о Земле. В первую очередь, это – задачи прогноза изменения климата, предсказание природных катаклизмов. 5) вычислительной химии. Разнообразные задачи этой области направлены на изучение свойств вещества в различных состояниях. 6) бизнес-приложениях. К этой категории относятся задачи, связанные с анализом финансовых рынков и прогнозирования курсов валют. Также распространены оптимизационные задачи, по формированию наилучшего варианта использования финансовых или иных ресурсов, построения оптимальных транспортных и телекоммуникационных сетей, размещения предприятий в регионе и многие другие задачи.

2. Есть мнение, что для написания программ MPI достаточно лишь 5-ти основых функций. Назовите их. Как Вы относитесь к данному высказыванию ?

1) Любая MPI-программа должна начинаться с вызова функции инициализации MPI (функция MPI_Init(&argc, &argv)) - создается группа процессов, в которую помещаются все процессы приложения, и создается область связи (объединяет все процессы приложения), описываемая предопределенным коммуникатором MPI_COMM_WORLD. 2) Функция завершения MPI программ MPI_Finalize()- закрывает все MPI-процессы и ликвидирует все области связи. 3) Функция определения номера процесcа MPI_Comm_rank(comm, &rank) – comm – коммуникатор, rank-номер процесса, вызвавшего функцию. 4) Функция передачи сообщения - MPI_Send(void* buf, int count, MPI_Datatype datatype, int dest,int tag, MPI_Comm comm) buf- адрес начала расположения пересылаемых данных;

count - число пересылаемых элементов; datatype - тип посылаемых элементов; dest - номер процесса-получателя в группе, связанной с коммуникатором comm; tag - идентификатор сообщения, comm - коммуникатор области связи. 5) Функция приема сообщения MPI_Recv(void* buf, int count, MPI_Datatype datatype, int source, int tag, MPI_Comm comm, MPI_Status *status) source - номер процесса-отправителя;status- атрибуты принятого сообщения.

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

Наши рекомендации