ãã ããçŸæç¹ã§ã¯ãæ¶è²»è åžå Žã§å©çšå¯èœãªäžŠååŠçã®ããŒããŠã§ã¢å®è£ ãšãµããŒãçšã®ãœãããŠã§ã¢ã«ã¯äžå®ã®ã®ã£ããããããŸãã ãã®ããããã«ãã³ã¢æ±çšã³ã³ãã¥ãŒã¿ãŒãçŸåšã®10幎åã°ã«æšæºã«ãªã£ãäžæ¹ã§ããã®ãããªã·ã¹ãã çšã®ããã°ã©ã ãéçºããããã®äžè¬çãªæšæºã§ããOpenMPã®åºçŸã¯ãã»ãŒ10幎åã«æ³šç®ãããŸãã[1]ã ã»ãŒåæã«ãåæ£ç°å¢ã®ããã»ã¹éã§ã¡ãã»ãŒãžã転éããæ¹æ³ã説æããMPIæšæºãçå®ãããŸãã[2]ã
ãã©ãã€ã ããªããžã§ã¯ãæåã®ã¢ãããŒãã«é©åãããã«æ©èœãæ¡åŒµããããšã§ã®ã¿è¡šçŸããããããã®æšæºã®äž¡æ¹ã®éçºã¯ãMicrosoft .NET Frameworkãªã©ã®ææ°ã®ããã°ã©ãã³ã°ãã©ãããã©ãŒã ãšäºææ§ããªããšããäºå®ã«ã€ãªãããŸãã ãã®ããããããã®ãã©ãããã©ãŒã ã®éçºè ã¯ã補åã«äžŠååŠçãå®è£ ããããã®è¿œå ã®åªåãããªããã°ãªããŸããã
[3]ã§ãèè ã¯ãããã®æè¡ã®1ã€ã§ããMicrosoft Parallel Extensionsãæ€èšããŸãããããã«ãããå ±æã¡ã¢ãªãåããã³ã³ãã¥ãŒã¿ãŒã®åæã·ãŒã±ã³ã·ã£ã«ãããŒãžã³ãŒãã«äžŠååŠçãå®è£ ããããªãç°¡åãªæ¹æ³ãå¯èœã«ãªããŸãã ãŸããç§åŠèšç®ã«.NET Frameworkã䜿çšããå¯èœæ§ãšäŸ¿å©ãã瀺ãããŸããã ããã«ãããããããã³ã³ãã¥ãŒãã£ã³ã°ã¯ã©ã¹ã¿ãªã©ã®åæ£ã¡ã¢ãªãåããã·ã¹ãã ã§ã®è€éãªèšç®ã«äœ¿çšãããããã°ã©ã ãéçºããããã®ãã®ãã©ãããã©ãŒã ã®é©çšæ§ã®åé¡ã¯æªè§£æ±ºã®ãŸãŸã§ãã ãããã®ã·ã¹ãã ã¯ãçžäºæ¥ç¶ãããã³ã³ãã¥ãŒãã£ã³ã°ããŒãã®ã»ããã«åºã¥ããŠããŸããåããŒãã¯ãç¬èªã®ããã»ããµãã¡ã¢ãªãI / Oãµãã·ã¹ãã ããªãã¬ãŒãã£ã³ã°ã·ã¹ãã ãåããæ¬æ Œçãªã³ã³ãã¥ãŒã¿ãŒã§ãããåããŒãã¯ç¬èªã®ã¢ãã¬ã¹ç©ºéã§åäœããŸãã
MPI äž»ãªã¢ã€ãã¢ãšæ¬ ç¹
é¢æ°åããã°ã©ãã³ã°ã®äžçã§ã¯ããã®ã¿ã€ãã®äžŠåã³ã³ãã¥ãŒã¿ãŒçšã®ããã°ã©ã ãäœæããããã®æãäžè¬çãªãã¯ãããžãŒã¯MPIã§ãã ãã®å Žåã®äžŠåããã»ã¹ã®çžäºäœçšã®äž»ãªæ¹æ³ã¯ãããããŒãããå¥ã®ããŒããžã®ã¡ãã»ãŒãžã®éä¿¡ã§ãã MPIæšæºã¯ãåã³ã³ãã¥ãŒãã£ã³ã°ãã©ãããã©ãŒã ã®ããã°ã©ãã³ã°ã·ã¹ãã ãšãŠãŒã¶ãŒãããã°ã©ã ãäœæããéã«å°éããå¿ èŠãããã€ã³ã¿ãŒãã§ã€ã¹ãä¿®æ£ããŸããMPIã¯FortranãšCããµããŒãããŸããMPIããã°ã©ã ã¯ãçžäºäœçšãã䞊åããã»ã¹ã®ã»ããã§ãã ãã¹ãŠã®ããã»ã¹ã¯äžåºŠçæãããããã°ã©ã ã®äžŠåéšåã圢æããŸãã åããã»ã¹ã¯ç¬èªã®ã¢ãã¬ã¹ç©ºéã§åäœããMPIã«ã¯å ±éã®å€æ°ãããŒã¿ã¯ãããŸããã ããã»ã¹éã®å¯Ÿè©±ã®äž»ãªæ¹æ³ã¯ãããããã»ã¹ããå¥ã®ããã»ã¹ãžã®ã¡ãã»ãŒãžã®æ瀺çãªéä¿¡ã§ãã [4]
MPIããã°ã©ã ã¯é«ãã¬ãã«ã®ããã©ãŒãã³ã¹ã瀺ããšããäºå®ã«ããããããããã¯ãããžãŒèªäœã«ã¯ããã€ãã®æ¬ ç¹ããããŸãã
- äœã¬ãã«ïŒMPIã§ã®ããã°ã©ãã³ã°ã¯ãã¢ã»ã³ãã©ãŒã§ã®ããã°ã©ãã³ã°ãšæ¯èŒãããããšãå€ãïŒãããã»ã¹éã®ã¡ãã»ãŒãžã®äº€æã ãã§ãªããé åã®åæ£ã®è©³çŽ°ãªå¶åŸ¡ãšããã»ã¹éã®ã«ãŒãã®å埩ã®å¿ èŠæ§-ããã¯ãã¹ãŠãããã°ã©ã éçºã®é«åºŠãªè€éæ§ã«ã€ãªãããŸã;
- éä¿¡ãããã¡ãã»ãŒãžã®ããŒã¿åã®éå°ãªæå®ã®å¿ èŠæ§ãããã³éä¿¡ãããããŒã¿ã®åã«å¯Ÿããå³æ Œãªå¶éã®ååšã
- ä»»æã®ãµã€ãºã®é åãšä»»æã®æ°ã®ããã»ã¹ã§å®è¡ã§ããããã°ã©ã ãèšè¿°ããã®ã¯è€éã§ãããããæ¢åã®MPIããã°ã©ã ãåå©çšããããšã¯ã§ããŸããã
- ãªããžã§ã¯ãæåã¢ãããŒãã®ãµããŒãã®æ¬ åŠã
ããã«ããããããã3çªç®ã®ããŒãžã§ã³ããã.NET Frameworkã«ã¯Windows Communication FoundationïŒWCFïŒãå«ãŸããŠããŸããããã¯ãMicrosoftãã©ãããã©ãŒã äžã§ããããçš®é¡ã®åæ£ã¢ããªã±ãŒã·ã§ã³ãäœæããããã®çµ±åãã¯ãããžãŒã§ã[5]ã æ®å¿µãªããããã®æè¡ã¯XMLããŒã¹ã®WebãµãŒãã¹ãæäœããããã®ãã¬ãŒã ã¯ãŒã¯ãšããŠããç解ãããŠããªãããšãå€ããWCFã䞊åã³ã³ãã¥ãŒãã£ã³ã°ãæŽçããããã®å¹æçãªããŒã«ãšèŠãªãããããšã¯ãããŸããã
WCFæ§é
åæ£ã¡ã¢ãªã·ã¹ãã çšã®ããã°ã©ã ãéçºããããã®ããŒã«ãšããŠWCFã䜿çšããå¯èœæ§ãå€æããããã«ããã®æè¡ã®åºæ¬ãæ€èšããŸãã WCFãµãŒãã¹ã¯ãã¯ã©ã€ã¢ã³ãã«ããã€ãã®æçšãªæ©èœãæäŸãããšã³ããã€ã³ãã®ã»ããã§ãã ãšã³ããã€ã³ãã¯ãåã«ã¡ãã»ãŒãžãéä¿¡ã§ãããããã¯ãŒã¯ãªãœãŒã¹ã§ãã æäŸãããæ©äŒã掻çšããããã«ãã¯ã©ã€ã¢ã³ãã¯ãã¯ã©ã€ã¢ã³ããšãµãŒãã¹éã®å¥çŽã§èšè¿°ããã圢åŒã§ãšã³ããã€ã³ãã«ã¡ãã»ãŒãžãéä¿¡ããŸãã ãµãŒãã¹ã¯ãã¡ãã»ãŒãžãåæããã圢åŒã§èšé²ããããšæ³å®ããŠãã¡ãã»ãŒãžããšã³ããã€ã³ãã¢ãã¬ã¹ã«å°çããã®ãåŸ ã£ãŠããŸããã¯ã©ã€ã¢ã³ãããµãŒãã¹ã«æ å ±ãéä¿¡ããã«ã¯ãã¢ãã¬ã¹ããã€ã³ãã£ã³ã°ãå¥çŽãšãããAPKããç¥ã£ãŠããå¿ èŠããããŸãã
ã¢ãã¬ã¹ã¯ããšã³ããã€ã³ããã¡ãã»ãŒãžãåä¿¡ã§ããããã«ãã¡ãã»ãŒãžã®éä¿¡å ã決å®ããŸãã
ãã€ã³ãã£ã³ã°ã¯ããšã³ããã€ã³ããšã®éä¿¡çšã®ãã£ãã«ãå®çŸ©ããŸãã WCFã¢ããªã±ãŒã·ã§ã³ã§åŸªç°ãããã¹ãŠã®ã¡ãã»ãŒãžã¯ããã£ãã«ãä»ããŠéä¿¡ãããŸãã ãã£ãã«ã¯ãããã€ãã®ãã€ã³ãã£ã³ã°èŠçŽ ã§æ§æãããŸãã æäžäœã¬ãã«ã§ã¯ããã€ã³ãã£ã³ã°èŠçŽ ã¯ãããã¯ãŒã¯ãä»ããã¡ãã»ãŒãžé ä¿¡ãæäŸãããã©ã³ã¹ããŒãã¡ã«ããºã ã§ãã äžèšã®ãã€ã³ãã£ã³ã°èŠçŽ ã¯ãã»ãã¥ãªãã£ããã³ãã©ã³ã¶ã¯ã·ã§ã³ã®æŽåæ§èŠä»¶ã説æããŠããŸãã WCFã«ã¯ãäžé£ã®å®çŸ©æžã¿ãã€ã³ãã£ã³ã°ãä»å±ããŠããŸãã ããšãã°ãbasicHttpBindingãã€ã³ãã£ã³ã°ã¯ã2007幎以åã«äœæãããã»ãšãã©ã®WebãµãŒãã¹ãžã®ã¢ã¯ã»ã¹ã«é©çšã§ããŸãã ãã€ã³ãã£ã³ã°netTcpBindingã¯ã2ã€ã®.NETã·ã¹ãã éã®éä¿¡çšã«TCPãããã³ã«ãä»ããé«éããŒã¿äº€æãå®è£ ããŸãã netNamedPipeBindingã¯ãåäžã®ãã·ã³å ãŸãã¯è€æ°ã®.NETã·ã¹ãã éã®éä¿¡çšã«èšèšãããŠããŸãã ãŸãããã¢ããŒãã¢ãããã¯ãŒã¯ã§åäœããã¢ããªã±ãŒã·ã§ã³ã®æ§ç¯ããµããŒãããŠããŸããããã«ã¯ãnetPeerTcpBindingãã€ã³ãã£ã³ã°ããããŸãã
ã³ã³ãã©ã¯ãã¯ããšã³ããã€ã³ãã«ãã£ãŠæäŸãããäžé£ã®æ©èœãã€ãŸãããšã³ããã€ã³ããå®è¡ã§ããæäœãããã³ãããã®æäœã®ã¡ãã»ãŒãžåœ¢åŒãå®çŸ©ããŸãã ã³ã³ãã©ã¯ãã§èª¬æãããŠããæäœã¯ããšã³ããã€ã³ããå®è£ ããã¯ã©ã¹ã®ã¡ãœããã«ããããããç¹ã«åã¡ãœãããšã®éã§åãæž¡ãããããã©ã¡ãŒã¿ãŒã®ã¿ã€ããå«ãŸããŸãã WCFã¯ãä»»æã®ããŒã¿åã®åæããã³éåæã®äžæ¹åããã³äºéæäœããµããŒãããŸããããã¯ã.NET Frameworkã«åºã¥ããŠåæ£ã¢ããªã±ãŒã·ã§ã³ãæ§ç¯ãã倧ããªèšç®åé¡ã解決ããã®ã«ååã§ãã ãã ããæäŸãããæ å ±ã¯ããã®å Žåã®WCFãã¯ãããžã®å®çšçãªé©çšæ§ãšæå¹æ§ã®è©äŸ¡ã«ã¯åœ¹ç«ã¡ãŸããã
WCFã®æå¹æ§ãè©äŸ¡ããæ¹æ³
次ã®äœçœ®ããWCFã®é©çšæ§ãè©äŸ¡ããŸãã- èšç®åé¡ã解決ããããã®åæ£ã¢ããªã±ãŒã·ã§ã³ãéçºããèœåãšè€éãã
- åæ£ã¢ããªã±ãŒã·ã§ã³ã®ã³ã³ããŒãã³ãéã®ããŒã¿äº€æã®å¹çã
- WCFã䜿çšããåæ£ã³ã³ãã¥ãŒãã£ã³ã°ã®å šäœçãªå¹çã
å¯èœæ§ã®å®äŸãšããŠãWCFã䜿çšããèšç®ã¿ã¹ã¯ã®ã¢ããªã±ãŒã·ã§ã³éçºã®è€éããè©äŸ¡ãããšãšãã«ãå ¬åŒã®MPIãªãœãŒã¹ã§èª¬æãããŠãããã¢ã¢ã«ãŽãªãºã ãå®è£ ããããšãææ¡ããŸã[6]ã
ãœãªã¥ãŒã·ã§ã³ã®ããã©ãŒãã³ã¹ããã¹ãããããã«ã4å°ãš2å°ã®åçã®ããã©ãŒãã³ã¹ã®ããã»ããµã³ã¢ãæèŒãã2å°ã®ã³ã³ãã¥ãŒã¿ãŒã䜿çšããŸãã éä¿¡ã¯ã€ãŒãµããã100Mbitçµç±ã§ãã WCFãã¹ãã¯Microsoft Windows 7 OSã§å®è¡ãããPelican HPC [7]ã¯Open MPI 1.3.3ã䜿çšããŠLinux 2.6.30ã«ãŒãã«ã§MPIã¯ã©ã¹ã¿ãŒãæ§ç¯ããããã«äœ¿çšãããŸãã
ç°¡åãªæ å ±äº€æããã°ã©ã
ã³ã³ãã¥ãŒã¿ãŒãããã¯ãŒã¯ã®ã³ã³ããŒãã³ãéã®ããŒã¿äº€æã®æå¹æ§ã瀺ãããã«èšèšãããæãåçŽãªãã¹ãã¯ãããããŒãããå¥ã®ããŒããžããŸãã¯ãã®éã«å粟床å®æ°ã®é åãéä¿¡ãããããã®æäœã«è²»ããããæéãä¿®æ£ããããšã§ãã MPIã®C ++ã³ãŒãã¯æ¬¡ã®ãšããã§ãã#define NUMBER_OF_TESTS 10
int main( argc, argv )
int argc;
char **argv;
{
double *buf;
int rank, n, j, k, nloop;
double t1, t2, tmin;
MPI_Status status;
MPI_Init( &argc, &argv );
MPI_Comm_rank( MPI_COMM_WORLD, &rank );
if (rank == 0)
printf( "Kind\t\tn\ttime (sec)\tRate (MB/sec)\n" );
for (n=1; n<1100000; n*=2) {
if (n == 0) nloop = 1000;
else nloop = 1000/n;
if (nloop < 1) nloop = 1;
buf = (double *) malloc( n * sizeof(double) );
tmin = 1000;
for (k=0; k<NUMBER_OF_TESTS; k++) {
if (rank == 0) {
t1 = MPI_Wtime();
for (j=0; j<nloop; j++) {
MPI_Ssend( buf, n, MPI_DOUBLE, 1, k, MPI_COMM_WORLD );
MPI_Recv( buf, n, MPI_DOUBLE, 1, k, MPI_COMM_WORLD,
&status );
}
t2 = (MPI_Wtime() - t1) / nloop;
if (t2 < tmin) tmin = t2;
}
else if (rank == 1) {
for (j=0; j<nloop; j++) {
MPI_Recv( buf, n, MPI_DOUBLE, 0, k, MPI_COMM_WORLD,
&status );
MPI_Ssend( buf, n, MPI_DOUBLE, 0, k, MPI_COMM_WORLD );
}
}
}
if (rank == 0) {
double rate;
if (tmin > 0) rate = n * sizeof(double) * 1.0e-6 /tmin;
else rate = 0.0;
printf( "Send/Recv\t%d\t%f\t%f\n", n, tmin, rate );
}
free( buf );
}
MPI_Finalize( );
return 0;
}
ãã®æäœã«ã¯ã2ã€ã®MPIããã»ã¹ãå¿ èŠã§ãããã®éã«ãMPI_RecvïŒïŒããã³MPI_Ssendã³ãã³ãã䜿çšããŠããµã€ãºã1ãã1048576ã®doubleèŠçŽ ã®é åã亀æããŸãã åè¿°ã®MPIæ¬ é¥ã®åœ±é¿ã«æ³šç®ãã䟡å€ããããŸãã
- äž¡æ¹ã®ããã»ã¹ã®æ©èœã®åé¢ã¯ãããã»ã¹ã®æ°ã®ã¿ã«åºã¥ããŠãããããã°ã©ã ããªã¹ããããšããèªèãè€éã«ããŸãã
- ããŒã¿ïŒMPI_SsendïŒãéä¿¡ããåã«ãåä¿¡åŽãåä¿¡ïŒMPI_RecvïŒãæ瀺çã«åæåããããšã確èªããå¿ èŠããããŸããããã«ãããéçºããã»ã¹ãè€éã«ãªããŸãã
- éä¿¡ãããããŒã¿ã®ã¿ã€ãïŒMPI_DOUBLEïŒãããŒã¿èªäœãšäžç·ã«æå®ããããšã¯ãåççãªèŠ³ç¹ããã¯äžèŠã§ãããããã°ã©ã ã®è«çãšã©ãŒã«ã€ãªããå¯èœæ§ããããŸãã
- ããã«ãããã°ã©ãã³ã°èšèªã®ç·šæã«é¢é£ããäžå¿«ãªç¬éã¯ãã¡ã¢ãªãæåã§å²ãåœãŠãã解æŸãããããå¿ èŠãããããšã§ãã
[ServiceContract(CallbackContract = typeof(IClientCallback))] public interface IServerBenchmark
{
[OperationContract(IsOneWay = true)] void SendArray(double[] array);
}
public interface IClientCallback
{
[OperationContract(IsOneWay = true)] void SendArrayFromServer(double[] array);
}
以äžã¯ãã¯ã©ã€ã¢ã³ãã¢ããªã±ãŒã·ã§ã³ããå®æ°ã®é åãåä¿¡ããŠââéä¿¡ãããµãŒããŒã¢ããªã±ãŒã·ã§ã³ã®ããžãã¯ãå®è£ ããã¯ã©ã¹ã«ã€ããŠèª¬æããŠããŸãã
public class ServerBenchmark : IServerBenchmark
{
public void SendArray(double[] array)
{
OperationContext.Current.GetCallbackChannel<IClientCallback>().SendArrayFromServer(array);
}
}
蟲æ¥ç£æ¥è€åäœãç»é²ãããµãŒããŒã¢ããªã±ãŒã·ã§ã³ã®ã¡ã€ã³ã¡ãœãããå®è£ ãããŸãã ãã®å ŽåããµãŒããŒã¢ããªã±ãŒã·ã§ã³ã®åäœã¯ãã³ãŒããšã¢ããªã±ãŒã·ã§ã³ã®.configãã¡ã€ã«ã®äž¡æ¹ã®èšå®ã«åŸã£ãŠæ§æã§ããŸãã
class Program
{
static void Main(string[] args)
{
ServiceHost serviceHost = new ServiceHost();
NetTcpBinding binding = new NetTcpBinding();
serviceHost.AddServiceEndpoint(typeof(IServerBenchmark), binding, "");
serviceHost.Open();
Console.ReadLine();
serviceHost.Close();
}
}
ã¯ã©ã€ã¢ã³ãã¢ããªã±ãŒã·ã§ã³ã¯æ¬¡ã®ãšããã§ããCallBackHandlerã¯ã©ã¹ã¯åè¿°ã®å¯Ÿå¿ããã€ã³ã¿ãŒãã§ã€ã¹ãå®è£ ããClientã¯ã©ã¹ã¯ãšã³ããªãã€ã³ããšããŠæ©èœããéçã¡ãœãããæäŸããŸãã
public class CallbackHandler : IServerBenchmarkCallback
{
private static EventWaitHandle _waitHandle = new EventWaitHandle(false, EventResetMode.AutoReset);
static int _totalIterations = 10;
public static DateTime _dateTime;
public void SendArrayFromServer(double[] array)
{
_waitHandle.Set();
}
class Client
{
private static InstanceContext _site;
static void Main(string[] args)
{
_site = new InstanceContext(new CallbackHandler());
ServerBenchmarkClient client = new ServerBenchmarkClient(_site);
double[] arr = new double[Convert.ToInt32(args[0])];
for (int index = 0; index < arr.Length;index++ )
arr[index] = index;
_dateTime = DateTime.Now;
for (int index = 0; index < _totalIterations; index++)
{
client.SendArray(arr);
_waitHandle.WaitOne();
}
Console.WriteLine((DateTime.Now - _dateTime).TotalMilliseconds / _totalIterations);
Console.ReadKey();
}
}
}
ããã°ã©ã ã¯ãããŒã¿é åãæž¡ããŠãªã¢ãŒãSendArrayã¡ãœãããåŒã³åºãããµãŒããŒããè¿ãããããŒã¿ãåä¿¡ããSendArrayFromServerã¡ãœãããžã®åŒã³åºããåŸ æ©ãããããã€ãã®å埩ãå®è¡ããŸãã
æ瀺ãããã³ãŒãã«ã¯ãMPIã«é¢ããããã€ãã®éèŠãªå©ç¹ããããŸãã
- ã€ã³ã¿ãŒãã§ãŒã¹ïŒå¥çŽïŒã«å®è£ ããããéä¿¡ããŒã¿ã®ãã©ãŒãããã®çµ±äžããã1åéãã®èšè¿°ã
- ãªã¢ãŒãã¡ãœããåŒã³åºãã®ç°¡åãªå®è£ ã
- ãªããžã§ã¯ãæåã®éçºã¢ãããŒãã䜿çšããŸãã
ãã®è¡šãããæ®å¿µãªãããWCFãã¯ãããžã¯ãå°ããªããŒã¿ã®é »ç¹ãªããã»ã¹é亀æãå¿ èŠãšããããã°ã©ã ã®éçºã«ã¯é©ããŠããŸããã
åæ£ã³ã³ãã¥ãŒãã£ã³ã°ã®äŸ
次ã«ãããŒãéã®ã¢ã¯ãã£ããªããŒã¿äº€æãå¿ èŠãšããªãåæ£ã¢ããªã±ãŒã·ã§ã³ãæ§ç¯ããå¯èœæ§ãæ€èšããŸãã åºç€ãšããŠããªãœãŒã¹[6]ããå¥ã®äŸãåãäžããŸã-æ°Piã®èšç®ã ãã®äŸã§ã¯ãPiã¯æ¬¡ã®ããã«èšç®ãããŸã ã ãã®ã¢ã«ãŽãªãºã ã®äžŠåæ§ã¯éåžžã«ç°¡åã«æ€åºã§ããŸããç©ååºéã¯ãèšç®ã«é¢äžããèšç®ããŒããšåãæ°ã®éšåã«åå²ãããŸãã åé¡ã解決ããMPIçšã®C ++ããã°ã©ã ã¯æ¬¡ã®ãšããã§ããint main(argc,argv)
int argc;
char *argv[];
{
int done = 0, n, myid, numprocs, i;
double PI25DT = 3.141592653589793238462643;
double mypi, pi, h, sum, x;
MPI_Init(&argc,&argv);
MPI_Comm_size(MPI_COMM_WORLD,&numprocs);
MPI_Comm_rank(MPI_COMM_WORLD,&myid);
while (!done)
{
if (myid == 0) {
printf("Enter the number of intervals: (0 quits) ");
scanf("%d",&n);
}
MPI_Bcast(&n, 1, MPI_INT, 0, MPI_COMM_WORLD);
if (n == 0) break;
h = 1.0 / (double) n;
sum = 0.0;
for (i = myid + 1; i <= n; i += numprocs) {
x = h * ((double)i - 0.5);
sum += 4.0 / (1.0 + x*x);
}
mypi = h * sum;
MPI_Reduce(&mypi, &pi, 1, MPI_DOUBLE, MPI_SUM, 0,
MPI_COMM_WORLD);
if (myid == 0)
printf("pi is approximately %.16f, Error is %.16f\n",
pi, fabs(pi - PI25DT));
}
MPI_Finalize();
return 0;
}
ã³ãŒãã¯éåžžã«ç°¡æœã§ãããäžèšã®MPIã®ãã¹ãŠã®æ¬ é¥ãç¹åŸŽã§ãã WCFã®å ŽåãCïŒã®ãµãŒããŒéšåã¯æ¬¡ã®ãšããã§ãã
[ServiceContract] public interface IPiService
{
[OperationContract] double CalculatePiChunk(int intervals, int processId, int processesCount);
}
public class PiService : IPiService
{
public double CalculatePiChunk(int intervals, int processId, int processesCount)
{
double h = 1.0 / (double)intervals;
double sum = 0.0;
double x;
for (int i = processId + 1; i <= intervals; i += processesCount)
{
x = h * (i - 0.5);
sum += 4.0 / (1.0 + x * x);
}
return h * sum;
}
}
public class Service
{
public static void Main(string[] args)
{
ServiceHost serviceHost = new ServiceHost(typeof(PiService));
serviceHost.AddServiceEndpoint(typeof(IPiService), new NetTcpBinding(), "");
serviceHost.Open();
Console.ReadLine();
serviceHost.Close();
}
}
ãµãŒããŒéšåã®å²ãåœãŠã¯ãã³ãŒãã®ç解ã容æã«ããã ãã§ãªããç¹å®ã®ã¯ã©ã€ã¢ã³ããåç §ããã«ã³ãŒããåå©çšããããšãå¯èœã«ããŸãã ã¯ã©ã€ã¢ã³ãèªäœã¯ã次ã®ããã«å®è£ ã§ããŸãïŒãªã¢ãŒãã¡ãœããCalculatePiChunkã¯ãåã³ã³ãã¥ãŒãã£ã³ã°ããŒãã§ç¬èªã®ãã©ã¡ãŒã¿ãŒã»ããã䜿çšããŠéåæçã«åŒã³åºãããŸãïŒã
class Client
{
private static double _pi;
private static DateTime _startTime;
static int _inProcess = 0;
static void Main(string[] args)
{
_pi = 0;
int intervals = Convert.ToInt32(args[0]);
List<String> endPoints = new List<string>();
for (int index = 1; index<args.Length;index++)
endPoints.Add(args[index]);
double pi = 0;
_inProcess = endPoints.Length;
PiServiceClient[] clients = new PiServiceClient[endPoints.Length];
for (int index = 0; index < endPoints.Length; index++)
clients[index] = new PiServiceClient("NetTcpBinding_IPiService", "net.tcp://" + endPoints[index] + "/EssentialWCF");
_startTime = DateTime.Now;
for (int index = 0; index< endPoints.Length; index++)
clients[index].BeginCalculatePiChunk(intervals, index, endPoints.Length, GetPiCallback, clients[index]);
Console.ReadKey();
}
static void GetPiCallback(IAsyncResult ar)
{
double d = ((PiServiceClient)ar.AsyncState).EndCalculatePiChunk(ar);
lock(ar)
{
_pi += d;
_inProcess--;
if (_inProcess == 0)
{
Console.WriteLine(_pi);
Console.WriteLine("Calculation ms elasped: " + (DateTime.Now - _startTime).TotalMilliseconds);
}
}
}
}
ããã©ãŒãã³ã¹ã®æž¬å®å€ã¯æ¬¡ã®ãšããã§ãã
ãããã®çµæã«åºã¥ããŠãå°æ°ã®ããã»ã¹ééä¿¡ã§åæ£ã³ã³ãã¥ãŒãã£ã³ã°ã¢ããªã±ãŒã·ã§ã³ãæ§ç¯ããããã®.NET Framework WCFãã¯ãããžãŒã®äœ¿çšã¯è¯ãçµæã瀺ããšå€æã§ããŸããæ¯èŒçäœãããŒã¿äº€æçã¯ã.NETã管çããæ¹æ³ã§ã®JITã³ãŒãã®å®æ§çæé©å[3]ã«ãã£ãŠè£ãããŸãå€ãã®ç¶æ³ã§ããã°ã©ã ã¯ããçç£çã§ãã
æ瀺ãããç°¡åãªãã¹ãã®çµæã«åºã¥ããŠã次ã®çµè«ãå°ãåºãããšãã§ããŸãã
- ãã©ãããã©ãŒã ã§ã®ã¢ããªã±ãŒã·ã§ã³éçºïŒåæ£ã¡ã¢ãªãåããã·ã¹ãã ã§èšç®äžã®åé¡ã解決ããããã®NET Frameworkãå¯èœã§ãã
- ãã®çš®ã®ã¢ããªã±ãŒã·ã§ã³ãæ§ç¯ããããã«èšèšãããWCFãã¯ãããžã¯ãMPIã§å®è£ ããããããã¯ããã«ç°¡åãªããã»ã¹ééä¿¡ã®æ¹æ³ãæäŸããŸãã
- åæ§ã«ããã®åçŽãã«ãããããŒã¿äº€æããã»ã¹ã®ããã©ãŒãã³ã¹ãå€§å¹ ã«äœäžããŸããå Žåã«ãã£ãŠã¯ãMPIã¯WCFããã2.5å以äžé«éã§ãã
- ãããã£ãŠãWCFã¯ãã³ã³ãã¥ãŒãã£ã³ã°ããŒãéã§å°ããªããŒã¿ã°ã«ãŒããéäžçã«äº€æããå¿ èŠãããåé¡ã®è§£æ±ºã«ã¯é©ããŠããŸããã
- ãã ãããŸããªããã»ã¹ééä¿¡ã®å Žåããã®ãã¯ãããžãŒã®äœ¿çšã¯éåžžã«æ£åœåãããŸã.MPIãšæ¯èŒããŠåçŽãªéçºæ¹æ³ã«å ããŠã.NET Frameworkã¯ãçµæã®ããã°ã©ã ã®çžäºéçšæ§ãèªåã¡ã¢ãªç®¡çãèšèªéã®çžäºäœçšãæ©èœã®ãµããŒããªã©ãç§åŠèšç®ãç·šæããããã®ãã®ä»ã®å©ç¹ãæäŸããŸãããã°ã©ãã³ã°ã [3]
æåŠ
1. OpenMPãªãã¡ã¬ã³ã¹ã OpenMPã¢ãŒããã¯ãã£ã¬ãã¥ãŒããŒãã2008 rã
2. MPI 2.1ãªãã¡ã¬ã³ã¹ã ããã·ãŒå€§åŠã2008 rã
3. .NETã§ã®äžŠåããã°ã©ãã³ã°ã ãã£ããããIãV.ã€ã«ã¯ãŒãã¯ã2009幎ãXIVãã€ã«ã«å šãã·ã¢äŒè°ãç§åŠãšç®¡çã«ãããæ å ±ãšæ°åŠæè¡ãã®è°äºé²ã
4.ã¢ã³ããããAãS. MPIãã¯ãããžãŒã䜿çšãã䞊åããã°ã©ãã³ã°ã MãïŒMSUåºç瀟ã
5.ã¬ã¹ããã¯ãã¹ãã£ãŒããã¯ã¬ãŒã³ããªãã£ãŒããããŒãšã³ãã¯ãªã¹ã .NET Framework 3.5ã®Windows Communication Foundationã®åºæ¬ã MãïŒDMK Pressã2008幎ã
6. Message Passing InterfaceïŒMPIïŒæšæºã www.mcs.anl.gov/research/projects/mpi
7. PelicanHPC GNU Linuxã pareto.uab.es/mcreel/PelicanHPC