5

ピクセル ベンダーに関するパフォーマンスに関する質問があります。多くの BitmapData を拡大したい (サイズを 2 倍にして新しい BitmapData にする)。私は as3 でこれを行っていましたが、パフォーマンスを向上させるためにピクセル ベンダーを使用したいと考えていました。私のマシンでは、as3よりもピクセル ベンダーのデモの方が優れたパフォーマンスを発揮します。

驚いたことに (または悪いコーディング/理解)、ピクセル ベンダーのパフォーマンスが大幅に低下しています - 2 秒対 1/2 秒! 少なくともas3 と同じパフォーマンスが得られると期待していました。私は何を間違っていますか?

簡単なピクセル ベンダー コードをここで入手しました(簡単に参照できるように以下に示します)。

package
{

import flash.display.BitmapData;
import flash.display.Shader;
import flash.display.ShaderJob;
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.geom.Matrix;

public class flashFlash extends Sprite
{


[Embed ( source="pixelbender/bilinearresample.pbj", mimeType="application/octet-stream" ) ]
private static var BilinearScaling:Class;

public function flashFlash( ):void
{
    stage.align = StageAlign.TOP_LEFT;
    stage.scaleMode = StageScaleMode.NO_SCALE;

    addEventListener( Event.ENTER_FRAME, efCb, false, 0, true );
}

private function efCb( evt:Event ):void
{
    removeEventListener( Event.ENTER_FRAME, efCb, false );

    traceTime( "init" );

    var srcBmd:BitmapData = new BitmapData( 80, 120, false, 0 );
    var destBmd:BitmapData = new BitmapData( 160, 240, false, 0 );

    var mx:Matrix = new Matrix( );
    mx.scale( 2, 2 );
    for (var i:uint = 0; i < 3000; i++)
    {   destBmd.draw( srcBmd, mx );
    }

    traceTime( "scaled with as3" );

    // create and configure a Shader object
    var shader:Shader = new Shader( );
    shader.byteCode = new BilinearScaling( );
    shader.data.scale.value = [.5];
    shader.data.src.input = srcBmd;

    for (var j:uint = 0; j < 3000; j++)
    {
        var shaderJob:ShaderJob = new ShaderJob( );
        shaderJob.shader = shader;
        shaderJob.target = destBmd;
        shaderJob.start( true );
    }

    traceTime( "scaled with pixel bender bilinearresample.pbj" );
}

private static var _lastTraceTime:Number = new Date().getTime();
public static function traceTime( note:String ):Number
{   var nowTime:Number = new Date().getTime();
    var diff:Number = (nowTime-_lastTraceTime);
    trace( "[t" + diff + "] " + note );
    _lastTraceTime = nowTime;
    return diff;
}

}
}

そして、ピクセル ベンダー コード:

<languageVersion : 1.0;>

kernel BilinearResample
<   namespace : "com.brooksandrus.pixelbender";
    vendor : "Brooks Andrus";
    version : 1;
    description : "Resizes an image using bilinear resampling. Constrains aspect ratio - divide Math.max( input.width / output.width, input.height / output.height ) and pass in to the scale parameter";
>
{
    parameter float scale
    <
        minValue: 0.0;
        maxValue: 1000.0;
        defaultValue: 1.0;
    >;

    input image4 src;
    output pixel4 dst;

    void
    evaluatePixel()
    {
        // scale should be Math.max( src.width / output.width, src.height / output.height )
        dst = sampleLinear( src, outCoord() * scale ); // bilinear scaling
    }
}
4

2 に答える 2

8

問題は、Pixel Bender を「actionscript」ではなく、ネイティブ プレーヤー コードと実際に比較していることだと思います。そのシナリオで Pixel Bender が勝つとは思えません。

ここで行われるスケーリングdestBmd.draw( srcBmd, mx );は、プレーヤーで直接コーディングされます。それはおそらくあなたが得ることができるのと同じくらい速いです(同等のアルゴリズムを使用して)。一方、カーネルを実行するには、少なくとも最初にコンパイル (または JIT コンパイル) する必要があります (おそらく、速度が遅くなる理由は他にもたくさんありますが、詳細についてはよくわかりません)。

Flash Player エンジニアのブログからこの投稿をチェックしてください。

昔、Flash Player の 8 日前に、ビットマップ フィルターを実行するための一般的な方法を追加するというアイデアがありました。Flash Player 8 で行ったようなビットマップ フィルターのハード コーディングは、柔軟性がないだけでなく、膨大な量のネイティブ コードをプレーヤーに追加し、プラットフォームごとに最適化する必要があります。私たちにとっての問題は、このような汎用フィルターをどのように作成するかということでした。さまざまなアイデアが飛び交いましたが、最終的に 1 つの問題が発生しました。言語もコンパイラもありませんでした。Macromedia が Adob​​e と合併した後、Flash Player と Adob​​e Pixel Bender チームが集まり、最終的に必要なもの、つまり言語とコンパイラを手に入れました。

したがって、基本的に、Pixel Bender は、Actionscript で直接ピクセルを操作するよりも高速です。setPixel および getPixel 呼び出しの同等の膨大な量よりも優れています。ただし、プレーヤー自体よりも高速になることはありません (これも同じアルゴリズムを使用します)。

ある意味では、あなたがやろうとしていることは、たとえば PB でグロー フィルターを書くようなものです。確かにクールだし、画像処理に興味があるならそこから多くのことを学べる。しかし、フィルターがネイティブ フィルターと同じように機能することを意図している場合、教育目的以外にはあまり意味がありません。ネイティブ フィルターはより高速であり、追加のコード行なしで既に利用可能です。

于 2010-05-18T01:44:13.597 に答える
2

ピクセルベンダーファイルなどへの接続処理は遅くなるが、処理自体は早いと聞いたのを漠然と覚えています。したがって、画像サイズが大きくなるにつれて、ピクセルベンダーフィルターが最終的により効率的になる可能性があることがわかると思います。あるいは、PixelBender は、もう少し複雑な画像操作用に保存するのが最適かもしれません。

于 2010-05-18T01:06:44.563 に答える