2010年3月26日 星期五

Very simple haXe coding tool



目前以文字編輯器寫haXe code好像只能做到初步語法檢查
所以我寫程式時總要在文字編輯器與haXe API Documentation之間不斷切換
這實在非常困擾我!!!
只好參考haXe Reflection API寫了個很陽春的haXe程式碼編寫工具
目前沒有語法檢查只有簡單的Code Asist功能
按'.'會跳出物件的Fields/Methods視窗
然後再用這工具編輯工具本身的程式碼

原本UI架構想採用AsWinghaxegui但嘗試haXe coding時很不順手,
後來還是改採簡簡單單的minimalcomps元件

目前的心得是haXe上手並不難
但是開發複雜一點的程式有點為難
希望我這個小工具可以幫上忙

Demo

2010年3月11日 星期四

Fast computing floating-point arrays using the Pixel Bender

前一陣子為了寫整合3D與Dynamic Sound相關套件的Flash程式,但是發覺只要加入的音頻越多的話,
常常會爆出破音甚至在IE上執行時會當掉,想說可能是Away3D吃掉太多資源所致,
也試著以Away3DLite改寫後情況也沒好到哪裡,最近剛好找到這篇文章Using Pixel Bender to calculate information
提到因為Flash是單一執行緒程式,當處理大量吃重的運算常效能不彰,
可利用Pixel Bender的多工處理的特性將某些吃重的運算挪到PBJ上面執行

於是參考這幾篇文章發表的程式碼後
Audio mixing with Pixel Bender
Using Pixel Bender with Flash Builder 4 beta as a number crunching engine

牛刀小試的改寫成了以下的程式碼

這是PBK程式碼,可多工平行運算用來加總兩個陣列的每個Item的值
<languageVersion : 1.0;>
kernel SumCalculator
<
namespace : "PixelBender";
vendor : "Charlie";
version : 1;
description : "SumCalculator";
>
{
input image1 src;
input image1 src2;

output pixel3 result;

void evaluatePixel()
{
float x = pixel1( sample(src, outCoord()) );
float y = pixel1( sample(src2, outCoord()) );

float z = x+y;

result = pixel3( z, 0.0, 0.0);
}
}


這是AS3程式碼
package
{

import com.bit101.components.*;

import flash.display.*;
import flash.events.*;
import flash.utils.*;

public class FastSumManyArray extends Sprite
{
[Embed(source="./pbks/SumCalculator.pbj", mimeType="application/octet-stream")]
private var KernelClass:Class;

const arraylength:int=5000;
private var array1:Array=new Array(arraylength);
private var array2:Array=new Array(arraylength);
private var array_result:Array=new Array();
private var text3:Text;
private var result:ByteArray;

public function FastSumManyArray()
{
stage.align="TL"
initArray(array1);
initArray(array2);
var text1:Text=new Text(this,0,0,array1.toString());
text1.height=16;
text1.width=1000;
addChild(text1);
var text2:Text=new Text(this,0,30,array2.toString());
text2.height=16;
text2.width=1000;
addChild(text2);
text3=new Text(this,0,60);
text3.height=16;
text3.width=1000;
addChild(text3);
addChild(new PushButton(this,0,100,"Start",clickHandler));
}

private function initArray(array:Array)
{
for(var i=0;i<array.length;i++)
{
array[i]=Math.random();
}
}

private function clickHandler(event:MouseEvent):void
{
initializeHandler(array1,array2);
}

protected function initializeHandler(list:Array, list2:Array):void
{
var byteArray:ByteArray = new ByteArray();
var byteArray2:ByteArray = new ByteArray();
var shader:Shader = new Shader(new KernelClass());
var shaderJob:ShaderJob;
var height:int;
var width:int;
byteArray = convertListToByteArray( list );
byteArray2 = convertListToByteArray( list2 );
width = byteArray.length >> 2;
height = 1;

shader.data.src.width = width;
shader.data.src.height = height;
shader.data.src.input = byteArray;

shader.data.src2.width = width;
shader.data.src2.height = height;
shader.data.src2.input = byteArray2;

result = new ByteArray();
result.endian = Endian.LITTLE_ENDIAN;

shaderJob = new ShaderJob(shader, result, width, height);
shaderJob.addEventListener(Event.COMPLETE, onComplete);
shaderJob.start();
}

protected function onComplete(event:Event):void
{
var length:int = result.length;
var num:Number;
var i:int;
result.position = 0;
for(i = 0; i < length; i += 4)
{
num = result.readFloat();
if(i % 3 == 0)
array_result.push(num);
}
text3.text=array_result.toString();
}



private static function convertListToByteArray(list:Array):ByteArray
{
var retVal:ByteArray = new ByteArray();
var number:Number;
var len:int = list.length;
var i:int;

retVal.endian = Endian.LITTLE_ENDIAN;

for (i; i<len; i++)
{
retVal.writeFloat( Number(list[i]) );
}

retVal.position = 0;

return retVal;
}

}
}



也可利用工具將PBJ反組譯成Assembly language,看看是否有改進的空間,再以HaXe重新組譯,
壓榨出最大的效能!!!

version : 1
name : 'SumCalculator'
meta namespace : 'PixelBender'
meta vendor : 'Charlie'
meta version : 1
meta description : 'SumCalculator'
param in f0.rg float2 _OutCoord
text0 1-channels src
text1 1-channels src2
param out f1.rgb float3 result
code :
sampleLinear f0.a, text0[f0.rg]
mov f0.b, f0.a
mov f0.a, f0.b
sampleLinear f1.a, text1[f0.rg]
mov f0.b, f1.a
mov f1.a, f0.b
mov f0.b, f0.a
add f0.b, f1.a
mov f2.r, f0.b
mov f2.g, f2.r
loadfloat f0.b, 0
mov f2.b, f0.b
loadfloat f0.b, 0
mov f2.a, f0.b
mov f1.rgb, f2.gba



這是執行結果的畫面



Demo