継続を使用する並列分散フレームワークのUnity実装 |
Ryo Yasuda, Shinji Kono
並列信頼研
|
ノードが接続している対象を直接知ることはできない
DG を取り出すためにCG内に宣言した変数データにannotation をつける。annotationには以下の4つがある。
digraph test {
node0 -> node1 [label="right"]
node1 -> node2 [label="right"]
node2 -> node0 [label="right"]
}
Java
public class StartHelloWorld extends StartCodeGear { }
@Override
protected void run(CodeGearManager cgm) { }
@Take String helloWorld;
C#
public class StartHelloWorld : StartCodeGear { }
public override void Run(CodeGearManager cgm) { }
[Take] string helloWorld;
public class StartHelloWorld : StartCodeGear {
public StartHelloWorld(CodeGearManager cgm) : base(cgm) { }
public static void Main(string[] args) {
CodeGearManager cgm = CreateCgm(10000);
cgm.Setup(new HelloWorldCodeGear());
cgm.Setup(new FinishHelloWorld());
cgm.GetLocalDGM().Put("helloWorld", "hello");
cgm.GetLocalDGM().Put("helloWorld", "world");
}
}
public class HelloWorldCodeGear : CodeGear {
[Take] string helloWorld;
public override void Run(CodeGearManager cgm) {
Console.Write(helloWorld + " ");
cgm.Setup(new HelloWorldCodeGear());
cgm.GetLocalDGM().Put(helloWorld, helloWorld);
}
}
public class FinishHelloWorld : CodeGear {
[Take] private string hello;
[Take] private string world;
public override void Run(CodeGearManager cgm) {
cgm.GetLocalDGM().Finish();
}
}
public class StartHelloWorld : StartCodeGear {
public StartHelloWorld(CodeGearManager cgm) : base(cgm) { }
public void RunCodeGear(CodeGearManager cgm) {
cgm.Setup(new HelloWorldCodeGear());
cgm.Setup(new FinishHelloWorld());
cgm.GetLocalDGM().Put("helloWorld", "hello");
cgm.GetLocalDGM().Put("helloWorld", "world");
}
}
public class HelloWorld : MonoBehaviour {
void Start() {
CodeGearManager cgm = StartCodeGear.CreateCgm(10000);
var helloWorld = new StartHelloWorld(cgm);
helloWorld.RunCodeGear(cgm);
}
}
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Take { }
[AttributeUsage(AttributeTargets.Field)]
public class Take : Attribute { }
public class MessagePackExample {
@Message
public static class MyMessage {
public String name;
public double version;
}
public static void main(String[] args) throws Exception {
MyMessage src = new MyMessage();
src.name = "msgpack";
src.version = 0.6;
MessagePack msgpack = new MessagePack();
// Serialize
byte[] bytes = msgpack.write(src);
// Deserialize
MyMessage dst = msgpack.read(bytes, MyMessage.class);
}
}
[MessagePackObject]
public class MyClass {
[Key(0)]
public int Age { get; set; }
[Key(1)]
public string FirstName { get; set; }
[Key(2)]
public string LastName { get; set; }
static void Main(string[] args) {
var mc = new MyClass {
Age = 99,
FirstName = "hoge",
LastName = "huga",
};
byte[] bytes = MessagePackSerializer.Serialize(mc);
MyClass mc2 = MessagePackSerializer.Deserialize<MyClass>(bytes);
// [99,"hoge","huga"]
var json = MessagePackSerializer.ConvertToJson(bytes);
Console.WriteLine(json);
}
}
Task は複雑な非同期処理を通常のコーディングと同じ感覚で直感的に記述できる
public class PriorityThreadPoolExecutors {
private static class PriorityThreadPoolExecutor extends ThreadPoolExecutor {
private static final int DEFAULT_PRIORITY = 0;
private static AtomicLong instanceCounter = new AtomicLong();
public PriorityThreadPoolExecutor(int corePoolSize, int maximumPoolSize,
int keepAliveTime, TimeUnit unit) {
super(corePoolSize, maximumPoolSize, keepAliveTime, unit, (BlockingQueue) new PriorityBlockingQueue<ComparableTask>(10,
ComparableTask.comparatorByPriorityAndSequentialOrder()));
}
@Override
public void execute(Runnable command) {
super.execute(command);
}
}
}
public class ThreadPoolExecutors {
public ThreadPoolExecutors(int nWorkerThreads, int nIOThreads) {
ThreadPool.SetMinThreads(nWorkerThreads, nIOThreads);
}
public void Execute(CodeGearExecutor command) {
Task.Factory.StartNew(() => command.Run());
}
}
Unityで使用されている既存のライブラリとして、Photon Unity Networking 2(PUN2)、MLAPIと、Christie # の比較を行う。
Christie # | PUN2 | MLAPI | |
---|---|---|---|
通信方式 | p2p | クライアントサーバ方式 | クライアントサーバ方式 |
プロトコル | TCP | TCP | TCP |
特徴 | 通信のためのIP address がプログラム直接記述されていない | Photon Cloud でサーバを自前で用意する必要がない | Unity公式でサポートされている RPC が使用可能 |