ActionScript Woker 間での ByteArray オブジェクトの共有

Flash Player 11.5 から、ActionScript Woker 間で ByteArray のオブジェクトを共有する機能が追加されました。

既に使用可能だった MessageChannel や SharedProperty を使ったオブジェクトの共有機能では、個々の Worker がそれぞれオブジェクトのコピーを保持します。そうすると、サイズの大きなデータ、例えばテクスチャなどを共有する場合、コピー用オブジェクト生成のための CPU 負荷やその保持に必要なメモリ量など、パフォーマンスに少なからず影響が出ることもありそうです。

一方、新しく追加された ByteArray の共有機能は、単一の ByteArray のオブジェクトを、複数の Worker から参照するというものです。そのため、データのコピー用に新たなオブジェクトの生成は不要ですし、当然、複製されたオブジェクトがメモリ領域を占めることもありません。

また、同一の ByteArray のオブジェクトを皆が参照するということで、ある Worker が ByteArray 内のデータを変更すると、それを共有する他の Worker にとっても値が変更されることになります。

(共有 ByteArray の変更を通知するイベントは無いので、変更した Worker 以外は、実際に値を確認しないと変更されたことは分かりません)

従来の MessageChannel や SharedProperty のように、それぞれの Worker がコピーを持つと、Worker が自分のコピーの値を変更しても、他の Worker の持つコピーには影響しません。新しい値を共有するには、再度オブジェクトを渡す作業が必要です。

このように、効率的なデータの共有手段であることと、データの更新が他の Worker にも直接影響すること、の 2 点が新しく利用できるようになった ByteArray 共有機能の特徴です。

ByteArray.shareable 属性

といっても、デフォルトの状態では、Worker の setSharedProperty() メソッドや MessageChannel の send() メソッドを使って ByteArray のオブジェクトを共有すると、新しく ByteArray のコピーが生成されます。同一のオブジェクトを複数の Worker が参照する、という状態にはなりません。

ByteArray のインスタンスを Worker 間で共有したいときは、共有する前に、shareable 属性の値を true に設定しておきます。それ以外のコーディングは、通常のオブジェクトの共有のときと同様です。

下は、setSharedProperty() メソッドを使って ByteArray オブジェクトを Worker 間で共有する例です。 (setSharedProperty() メソッドの解説はActionScript Worker (Flash Player マルチスレッド) の基本的な使い方をご覧ください)

import flash.display.Sprite;
import flash.system.Worker;
import flash.system.WorkerDomain;
import flash.utils.ByteArray;
 
public class sharedByteArraySample extends Sprite
{
  private var sharedByteArray:ByteArray;
 
  public function sharedByteArraySample()
  {
    if (Worker.current.isPrimordial) // 親Worker
    {
      // ByteArrayオブジェクトを生成し、shareableの値をtrueにする
      sharedByteArray = new ByteArray();
      sharedByteArray.shareable = true;
 
      // Workerを生成してByteArrayオブジェクトを共有する
      var w:Worker;
      w = WorkerDomain.current.createWorker(loaderInfo.bytes);
      w.setSharedProperty("sharedByteArray", sharedByteArray);
      w.start();
 
      // 以後適当に必要な処理を記述
    }
    else // ここから子Workerの記述
    {
      // 共有されたByteArrayオブジェクトへの参照を取得する
      sharedByteArray =  Worker.current.getSharedProperty(
        "sharedByteArray") as ByteArray;
 
      // 以後適当に必要な処理を記述
    }
  }
}

上記のように shareable 属性の値が true の ByteArray のオブジェクトが Worker から Worker に渡されると、データのコピーは行われません。代わりに、共有された ByteArray オブジェクトへの参照が渡されます。

アトミックな ByteArray の操作

従来提供されている ByteArray のメソッドはいわゆるスレッドセーフではありません。つまり、共有されている ByteArray オブジェクトに対して、ある Worker がアクセス中に、他の Worker が割り込んでくる可能性があります。

例えば、複数の Worker が同時に同じインデックスのデータを更新しようとするかもしれません。もちろん、その場合、結果がどうなるかは保証の限りではありません。

結果が保証されないのでは怖くてデータ更新もできません。そのため、新しく 2 つのアトミックなメソッドが追加されました。

ここで言うアトミックとは、メソッドの呼び出しから完了まで、他の Worker がメソッドの結果に影響する処理を行わないことが保障されている、という意味です。そのため、他の Worker からの邪魔を気にせず更新処理を行えます。

  • public function atomicCompareAndSwapLength(expectedLength:int, newLength:int):int
  • public function atomicCompareAndSwapIntAt(byteIndex:int, expectedValue:int, newValue:int):int

まず、1 つ目のメソッドは atomicCompareAndSwapLength() です。これは、ByteArray オブジェクトの length 属性の値を変更する、つまり ByteArray のサイズを変更するメソッドです。

単純に変更を行うのではなく、最初の引数と実際の length の値を比較して、両者が一致したときのみ変更が行われます。新しい length の値は 2 つ目の引数に指定します。

現在の値として把握している lenght の値が、他の Worker によって既に変更されていた場合は変更が行われない、というのが、単純に length 属性に値を設定する場合との違いです。

メソッドの戻り値はメソッド実行前の length の値なので、これを確認すれば、変更が行われたかどうかを判定できそうです。

2 つ目のメソッドは atomicCompareAndSwapIntAt() です。こちらは ByteArray オブジェクト内のデータを書き換えるメソッドです。

書き換える前に、実際の値を確認する点はこのメソッドも同様です。position を指定して writeInt() 相当の機能を実行するまでがアトミックに行われます。

引数は 3 つあり、先頭から順番に、変更する値の ByteArray 内のインデックス、変更前の実際の値として把握している数値、新しく設定したい数値、です。メソッドからの戻り値は、メソッドを実行する直前のインデックスで指定された位置の値です。

どちらのメソッドも、実際の値を確認してから変更を行うことで、不用意な 、他の Worker による変更が行われていることを確認せずに値を上書きしてしまう、という状況を避けられるようにデザインされています。

もし、単純な値の変更だけ行えればよいケースであれば、この 2 つのメソッドだけでも対応できるかもしれませんが、もっと自由に ByteArray オブジェクトを使いたい、既存のコードを簡単に再利用したい、という場合もあると思います。そんなときは、Mutex や Condition という新しく追加されたクラスが利用できるようになっています。

 

トラックバック(0)

トラックバックURL: http://cuaoar.jp/mt4/mt-tb.cgi/379

コメント(1)

勉強になりました

コメントする

2014年1月

Sun Mon Tue Wed Thu Fri Sat
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31  
レンタルサーバー

月別 アーカイブ

Powered by Movable Type 4.261