Язык Charm ++

Post on 15-Jan-2016

88 views 0 download

description

Язык Charm ++. Идеология Charm++. Charm++ - объектно-ориентированный язык программирования (расширение Си++), ориентированный на вычисления, управляемые потоком данных ( data-driven computations). Историческая справка. - PowerPoint PPT Presentation

Transcript of Язык Charm ++

Язык Charm ++

Идеология Charm++

Charm++ - объектно-ориентированный язык программирования (расширение Си++), ориентированный на вычисления, управляемые потоком данных (data-driven computations).

Историческая справка

• Начало работ – конец 80-х годов в лаборатории параллельного программирования университета Illionois Urbana-Campaighn

• Первая открытая реализация – 1993• В 1999-2000 годах добавлены

возможности динамической балансировки и перемещаемые объекты

Сущности Charm++

• «Последовательные» объекты

• «Распределяемые» объекты (chare)

• Сообщения

• Группы объектов

• Массивы объектов

Составляющие Charm++ приложения

• Файлы с описанием интерфейса ко всем объектам, кроме последовательных.

• Файлы с реализацией интерфейсов на Си ++.

file.ci

module.def.hmodule.decl.h

module.C

prg

charmc

c++c++

Компиляция в Charm++

CHARM=/home/posypkin/UTILS/charm-5.8/bin/charmchello: hello.o

$(CHARM) -o hello hello.o -language charm++

hello.o: hello.C $(CHARM) -c hello.C

hello.C: Hello.decl.h Hello.def.htouch hello.C

Hello.decl.h Hello.def.h: hello.ci$(CHARM) hello.ci

Модель выполнения Charm ++ приложения

узел

процессор

Создание объектов Charm ++

RTS

mainchare

chare

Распределяемые объекты Charm ++

Помимо обычных методов присутствует один или более входных (entry) методов, используемых для удаленного вызова.

«Главные» объекты (mainchare)

Один или несколько типов объектов должны наследовать mainchare. Они создаются системой поддержки времени выполнения в начале выполнения программы на процессоре с номером 0.

Описание в интерфейсном модуле

Один или несколько типов объектов должны наследовать mainchare. В интерфейсном модуле описание выглядит так:

mainchare HelloMain {

entry HelloMain();

entry void printDone();

};

Реализация Конструктор главного объекта имеет параметр по-умолчанию типа CkArgMsg*, через который передаются параметры командной строки:

HelloMain(CkArgMsg* m) {mCount = atoi(m->argv[1]);

delete m;

}

Взаимодействие объектов

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

прокси

объект

Передача параметров методу

• Через параметры. Используется маршалинг (упаковка/распаковка) параметров.

• Через специальные объекты – сообщения (message).

Маршалинг параметров

Маршалинг параметров базовых типов поддерживается системой. Для маршалинга параметров типов определенных пользователем требуется перегрузка метода pup или операции “|”:

void pup(PUP::er p){ p | mA; p | mB;}

hello.cimainmodule Hello { readonly CProxy_HelloMain mainproxy;

mainchare HelloMain {entry HelloMain();entry void printDone();

};

chare Slave { entry Slave(); entry void hello(int); }

};

hello.C#include <stdlib.h>#include "Hello.decl.h“

CProxy_HelloMain mainproxy;

class HelloMain : public Chare{public: HelloMain(CkArgMsg* m)

{ mCount = atoi(m->argv[1]); ckout << "Running " << CkNumPes() <<

" processors on " << CkNumNodes() << " nodes " << endl; mainproxy = thishandle; for(int i = 0; i < mCount; i ++) {

CProxy_Slave proxy = CProxy_Slave::ckNew();proxy.hello(i);

} delete m; }

void printDone() { mCount --; if(mCount == 0)

CkExit();}

private: int mCount;};

class Slave : public Chare {public: Slave() {} void hello(int i)

{ ckout << "Hello from " << i << " on " << CkMyPe() << " processor "

<<endl; mainproxy.printDone();}

};

#include "Hello.def.h"

Сообщения

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

Сообщения – объекты C++, объявленные в интерфейсном модуле с ключевым словом message:

message MyMessageType;

entry myMethod(MyMessageType* m);

Создание и передача сообщения в программе

class MyMessageType : public CMessage_MyMessageType {

int a;float b;

}

Сообщения создается с помощью оператора new:

MyMessageType *m = new MyMessageType();

proxy.myMethod(m);

При каждом вызове сообщение должно создаваться заново, т.к. при вызове оно удаляется!

Сообщения переменной длины Объявление в интерфейсном модуле:message Vec{ int a[];}

Объявление в C++ файле:class Vec { int* a;};

Создание: Vec *m = new (10) Vec(…);

Поиск максимума в массивеmainmodule Msort {

message Vec {

int vect[]; };

mainchare MsortMain {entry MsortMain();

};

chare Msort{ entry Msort(); entry void sort(Vec * ); entry void sortDone(int val); }};

#include <stdlib.h>#include "Msort.decl.h"

void copyarray(int* dest, int* source, int len){ for(int i = 0; i < len; i ++) {

dest[i] = source[i]; } ckout << endl;}

class Vec : public CMessage_Vec {public: CkChareID mProxy; int mInit; int mLen; int* vect; Vec(int ); Vec(int, CkChareID);};

Vec::Vec(int len){ mInit = 1; mLen = len;}

Vec::Vec(int len, CkChareID proxy){ mInit = 0; mLen = len; mProxy = proxy;}

class MsortMain : public Chare{public: MsortMain(CkArgMsg* msg)

{ int n; int* array;

delete msg; ckout << "Enter N: " << endl; ckin >> n; array = new int[n]; for(int i = 0; i < n; i ++) {

ckout << "Enter " << i << "-th element: " << endl;ckin >> array[i];

} Vec* m = new (n, 0) Vec(n); copyarray(m->vect, array, n); CProxy_Msort proxy = CProxy_Msort::ckNew(); proxy.sort(m);}

};

class Msort : public Chare {public: Msort()

{ mCount = 0;}

void sort(Vec* v){ ckout << "vector of " << v->mLen << " elements received " << endl; mInit = v->mInit;

if(!mInit)mProxy = v->mProxy;

if(v->mLen == 1) {CProxy_Msort proxy(mProxy);proxy.sortDone(v->vect[0]);

} else {int l1;int l2;

l1 = v->mLen / 2;l2 = v->mLen - l1;

Vec* m1 = new (l1, 0) Vec(l1, thishandle);copyarray(m1->vect, v->vect, l1);CProxy_Msort proxy = CProxy_Msort::ckNew();proxy.sort(m1);

Vec* m2 = new (l2, 0) Vec(l2, thishandle);copyarray(m2->vect, v->vect + l1, l2);proxy = CProxy_Msort::ckNew();proxy.sort(m2);

} }

void sortDone(int val) {

if(mCount == 0)mVal = val;

elsemVal = MYMAX(val, mVal);

mCount ++; if(mCount == 2)

if(mInit) { ckout << "Maximum = " << mVal << endl; CkExit();}else { CProxy_Msort proxy(mProxy); proxy.sortDone(mVal);}

}

private: bool mInit; int mCount; int mVal; CkChareID mProxy;

};