Alchemy之二值化圖像
因為所有算法相關的計算都用C實現,因此生成的SWF性能明顯比純AS實現的同樣功能要高效很多很多,幀率為24fps,CPU消耗30%,完全不卡,很爽很爽~~
有興趣的話可以下載源碼和演示~~
也可以點這裡直接在瀏覽器上試試,需要Flash Player 10
Posted In
actionscript,
alchemy,
c
|
0
意見
|
Alchemy之 Memory to ByteArray
A: 可將將數據塊的首指針地址返回給AS以讀取其中數據,具體看下面代碼:
比如說我們在C裡創建了一個整型數組,要返回給AS:
static AS3_Val myfun(void *self, AS3_Val args){
int buffer[4] = {1, 2, 3, 4};
return AS3_Array("IntType, AS3ValType", AS3_Int(4), AS3_Ptr(buffer));
}
然後在AS裡進行讀取:var loader:CLibInit = new CLibInit();
var clib:Object = loader.init();
var rs:Array = clib.myfun();
var len:init = rs[0];
var ptr:uinit = rs[1];
var ns:Namespace = new Namespace("cmodule.ModuleName");
var memory:ByteArray = (ns::gstate).ds;
memory.position = ptr;
var i:int;
for(i = 0; i < len; i ++){
trace(memory.readInt());
}
Posted In
actionscript,
alchemy,
c
|
0
意見
|
Alchemy之讀取AS ByteArray數據類型
//讀取AS傳入的ByteArray類型數據
static AS3_Val readByteArray(void *self, AS3_Val args)
{
//提取ByteArray
AS3_Val data = AS3_Undefined();
AS3_ArrayValue(args, "AS3ValType", &data);
//獲取ByteArray長度
AS3_Val prop = AS3_String("length");
int length = AS3_IntValue(AS3_Get(data, prop));
int i, tmp;
char buffer[128];
for (i = 0; i < length; i ++){
//讀取ByteArray裡的值並輸出到終端顯示
tmp = AS3_IntValue(AS3_Get(data, AS3_Int(i)));
sprintf(buffer, "[%d] : %d", i, tmp);
sztrace(buffer);
}
return AS3_Null();
}注意一下AS3_Get這個函數,它用于獲取一個AS Object obj的指定屬性prop,屬性用一個AS String字符串來表示,其函數定義為:AS3_Val AS3_Get(AS3_Val obj, AS3_Val prop)
如果obj不存在指定屬性,則函數返回NULL
然後在AS裡寫如下代碼來調用C函數並傳入ByteArray參數:
//初始化Alchemy var loader:CLibInit = new CLibInit(); var lib:Object = loader.init(); //創建一個ByteArray並寫入點數據 var bytes:ByteArray = new ByteArray(); bytes.writeByte(10); bytes.writeByte(20); bytes.writeByte(255); //調用C函數 lib.readByteArray(bytes);測試結果如下:
[0] : 10
[1] : 20
[2] : 255
PS : 另外在C代碼裡,除了AS3_Get(data, AS3_Int(i))外,還可以用如下方法讀取ByteArray:
unsigned char rs; AS3_ByteArray_seek(data, 0, SEEK_SET); AS3_ByteArray_readBytes(&rs, data, 1); 傳說中這樣比較高效~~AS3_ByteArray_seek
AS3_ByteArray_readBytes
AS3_ByteArray_writeBytes
這三個函數是C用來操作ByteArray的,詳細用法請自行參閱Alchemy API
Posted In
actionscript,
alchemy,
c
|
0
意見
|
初試 Adobe Alchemy
先看看C的代碼:
#include <stdlib.h>
#include <stdio.h>
#include "AS3.h"
//供AS調用的函數,args即為AS傳入給C函數的參數
static AS3_Val myfun(void *self, AS3_Val args)
{
//提取參數
int a, b;
AS3_ArrayValue(args, "IntType, IntType", &a, &b);
//計算a, b之和,轉換為AS裡的Int數據類型並返回之
return AS3_Int(a+b);
}
int main()
{
//定義一個公開給AS調用的函數
AS3_Val myMethod = AS3_Function(NULL, myfun);
//創建一個持有該函數引用的Object
AS3_Val result = AS3_Object("myfun:AS3ValType", myMethod);
//Release
AS3_Release(myMethod);
//告知初始化完成,此方法不會返回
AS3_LibInit(result);
//永遠不會執行到這裡
return 0;
}下面是AS代碼:
package{
import flash.display.Sprite;
import flash.utils.ByteArray;
import cmodule.test.CLibInit;
public class Test extends Sprite
{
public function Test()
{
var loader:CLibInit = new CLibInit();
var lib:Object = loader.init();
trace(lib.myfun(10, 20));
}
}
}OK,然後編譯一下:C: gcc test.c -O3 -Wall -swc -o test.swc
AS: mxmlc -library-path+=test.swc Test.as
Posted In
actionscript,
alchemy,
c
|
0
意見
|
[轉載] 划时代的 Adobe Alchemy
Adobe 自从2007年中推出了AS3支持了面向对象的开发方式之后, 可谓动作不断. 去年又将AVM2的核心虚拟机tamarin 捐赠给了ECMA4 , 又将FlexBuild2直接升级到FlexBuild3, 这不,在08年末,又蹦出一个 Adobe Alchemy, 这在战略上具有极为重要意义. 而FLASH 从一个简单的动画客户端,一跃升级成一个未来富媒体应用程序的平台. 从这一系列战略步骤,不难看出ADOBE想成为WEB乃至桌面开发霸主的野心! 微软你要小心了.
那么你可能要问了, 为什么Alchemy这么重要呢? 作为FLASH实践者, 效率问 题是众所周知的. 因为, FLASH中运行的代码是 ACTIONSCRIPT, 它是一个脚本语言.而这个语言是运行在FLASH内部的AVM2虚拟机上的. 所以它的一些功能都需要经过, 语言解释成AVM2虚拟机字节码,然后AVM2运行字节码,最后由本地NATIVE语言,也就是本机2进制程序执行.虽然这解决了平台无关的问题,但是带 来一个副作用,就是比较慢,这就是为什么FLASH上一直没有杀手级应用的主要原因.
从本质上来说, 这是一个构架上的问题. 而Alchemy 的出现,从构架上,改进了这个问题,你可以使用C/C++编写核心,快速的算法,让AS3进行调用, 达到加速的目标. 这在过去,你只能使用ADOVE提供给你的内置native 程序. 现在,你可以自己干这件事情了. 既解决了平台无关的问题,又解决了效率的问题,甚至可以利用FLASH本身几十亿现有的客户端的优势,解决了渠道问题.可以这样说, Alchemy 打开了一个前所未有的时代!
让我们看看 Alchemy 到底做什么. 从ADOBE的说明文档上可以看到, Alchemy 是一个 运行在低层的虚拟机 (Low Level Virtual Machine) ,他运行在AVM2之下. 那你又要问了.既然有了一个虚拟AVM2了,为什么还要一个LLVM? 其实, LLVM 将C/C++代码进行编译, 并且生成RISC-LIKE指令的字节码, 存储在缓冲区之中, 在FLASH运行开始的时候, 实时翻译成机器相关的本地代码. 需要调用的时候是调用翻译之后的2进制本地代码.以此来提高整体速度.这就是LLVM的关键技术, 而运行时译 (Runtime-Compile) 这种技术有点像 .NET . 而这种LLVM和AVM2的区别是, AVM2实时解释运行脚本代码,LLVM 预编译本地运行.可以这样认为 AVM2 是 JAVA虚拟机, LLVM是 .NET虚拟机.他们在构架上处于不同的层次,满足不同需求对速度的要求.
当生成编译完成后,字节码需要保存在一个缓冲区之内. 由于在框架之内需要和AVM2兼容,所以这个缓冲区,将以 AVM2能识别的BYTEARRAY 形式保存在内存之中. 即使使用反编译工具,反编译这个SWF文件,也看不到任何代码. 并且, alchemy自动生成一个 AS3的接口文件,以方便AS3程序进行调用. 值得注意的是, 所有C/C++编译之后的数据,都以 SWC 函数库的形式生成, 用户可以在自己的工程里 IMPORT.经过使用后发现,由 Alchemy 生成的SWC文件是比较大, 比 C/C++源文件大的多.即使一个只有几十来行的纯C 功能,生成SWC后都会有100多KB. 参考ADOBE的文档上说, 编译C/C++的代码,会将C/C++所需要的所有库,比如C标准库 统统放到一个SWC里去,并且严格遵循POSIX标准. (可移植操作系统接口) 由于这种机制的存在, 我们甚至可以在C/C++里嵌入线程的支持, 来运行同步或者异步的功能. 从而弥补了FLASH是单线程这一不足! 这将是一件美妙的事情! 而本人认为,由于C/C++代码是公用一个C标准库的,所以只要SWC中的功能越多,那么从空间效率上就越是划算. 并且在目前的宽带之下,多个100来KB问题不是太大.
当然,安全问题,也是alchemy的重头戏, 我们知道, FLASH 对安全问题是有一套非常严格的措施的,比如访问本地资源后,就不能访问远程资源,访问这个域的资源后,就不能访问其他域的资源.如果你要访问,就要在另外 一个域上安装一个沙箱(SecurityBox)文件,才能顺利访问. 而alchemy将C/C++带入FLASH之中,而C/C++ 是否能坏了这个规矩,让应用程序出轨呢? 答案当然是否定的,一旦这个程序被调用之后,其C/C++程序被严格的运行在一LLVM上,LLVM作为一个代理机构,向上,提供了对C/C++的平台支 持,比如独立的内存空间,独立的堆栈空间,独立的线程管理机构,等等. 向下将2进制程序输送到 本机CPU进行执行. 所以安全问题上是非常到位的, 所以对C/C++来说,只要LLVM环境没有提供的,它将永远访问不到.
Adobe已经对 alchemy 进行了比较深度的优化,并且我相信以后将继续下去.就从用户来说,由于有了alchemy 的出现,一些对速度要求较高的算法,都可以使用C/C++来代替. 由于接口上都是AS3的接口,所以移植现有的程序将会非常轻松.比如目前游戏开发中广泛使用的那个BitmapData.CopyPixel 如果用C纯代码进行改写,那么速度将提高几十倍之多.
总结. Alchemy 的出现,开启了一个全新的时代, 未来你将会发现网业上不再是简单画面,而是充满动态的不同的效果,给于用户全新的体验.随着LLVM提供的功能加多,比如将显卡硬件的功能作为一个抽象接口提供给C/C++调用,那么将来UNREAL3出现在网页上,你千万不要惊奇.甚至WOW出现在网页上,你也不要惊奇. 因为新时代的门已经打开!
Posted In
actionscript,
alchemy,
c,
c++
|
0
意見
|
Erlang创建进程到底有多快?
为了证实Erlang传说中“Crazy Fast”的进程创建速度,今天特意在自己机上(AMD 3600+ 双核,1G内存,Ubuntu 8.10操作系统)测试了一下Erlang创建进程的时间,所用代码如下:
-module(test).
-export([start/1]).
%记录开始时间并开始生成指定数量进程
start(Num) ->
statistics(wall_clock),
spawnProcesses(Num).
%所有进程生成完后输出所耗时间
spawnProcesses(0) ->
{_,Time}=statistics(wall_clock),
io:fwrite(”Total Time : ~p\n”,[Time]);
%生成进程
spawnProcesses(Num) ->
spawn(fun() -> doSomething(Num) end),
spawnProcesses(Num-1).
%什么都不做的进程~~
doSomething(Num) -> Num.
运行Erlang虚拟机编译&运行:
1> c(test).
{ok,test}
2> test:start(1000000).
4768
….
统计结果表明Erlang生成一百万个进程约需4.7秒,亦即平均下来生成一个进程仅需4.7us,确实是很短的时间了~~但没有对比说明不了什么,与C生成线程的速度比哪个更快些呢?马上写段C代码看看:
#include
#include
#include
//什么都不干的线程~~
void thread(){}
//主函数
int main(){
int i;
clock_t start,end;
//记录开始时间
start=clock();
//生成很多很多线程
for(i=0;i<100000;i++){
pthread_t id;
pthread_create(&id,NULL,(void *)thread,NULL);
}
//记录结束时间
end=clock();
double time=(double)((end-start)/CLOCKS_PER_SEC);
printf(”Total Time : %f\n”,time);
}
编译运行命令如下:
gcc test.c -lpthread
./a.out
统计表明C生成十万进程就已经需要接近4秒了,比Erlang慢了接近10倍,看来Erlang疯快的轻量级进程不是浪的虚名的~~不过有好长时间没写C了,如果上面代码或测试方式有任何问题,欢迎留言提出大家讨论讨论~~
Posted In
c,
erlang,
process,
thread
|
0
意見
|
Erlang通过Port与C交互

Port相关命令如下:
打开端口:Port=open_port(PortName,PortSettings).
发送数据:Port ! {PidC, {command, Data}}.
转换连接进程:Port ! {PidC, {connect, Pid}}.
关闭端口:Port ! {PidC, close}.
接收数据:receive {Port,{data,Data}} -> …. end.
例如下面的代码,Erlang先打开一个端口,传送一串字符串给外部的C++程序,外部程序原样返回该字符串:
先看看外部的C++代码:#include <iostream>
using namespace std;
int main(){
char str[128];
cin.getline(str,128);
cout << "Data receive in C : " << str << endl;
}
然后系Erlang的代码:
-module(test).
-export([start/0]).
start() ->
%打开端口并接收数据
Port=open_port({spawn,”./ctest”},[{line,1024}]),
Port!{self(),{command,“I am Oscar! 123456\n”}},
receive
{Port,{data,{eol,Msg}}} ->
io:fwrite(”Receive : ~s\n”,[Msg])
end,
%关闭端口
Port!{self(),close}.
两段代码编译后在erlang虚拟机中运行:
1> test:start().
Receive : Data receive in C : I am Oscar! 123456
{<0.31.0>,close}
Posted In
c,
erlang,
port
|
0
意見
|
在Erlang中生成随机数
Erlang中生成随机数要使用random模块,首先讲讲主要用到的函数:
Types: A1 = A2 = A3 = int()
Seeds random number generation with integer values in the process dictionary, and returns the old state.One way of obtaining a seed is to use the BIF now/0:
…
{A1,A2,A3} = now(),
random:seed(A1, A2, A3),
…
Returns a random float uniformly distributed between 0.0 and 1.0, updating the state in the process dictionary.
Types: N = int()
Given an integer N >= 1, uniform/1 returns a random integer uniformly distributed between 1 and N, updating the state in the process dictionary.
例子:
-module(test).
-export([start/0]).
%设定状态并开始生成随机数
start() ->
{A1,A2,A3}=now(),
random:seed(A1,A2,A3),
generateRandom(4).
%生成N个随机数
generateRandom(0) -> ok,
generateRandom(N) ->
io:fwrite(”~p/n”,[random:uniform(10)]),
generateRandom(N-1).
另附一段C生成随机数的代码:
#include
#include
#include
int main(){
int i;
srand(time(NULL));
for(i=0;i<4;i++){
printf(”%d : %d\n”,i,rand());
}
}
感觉和Erlang大同小异~~
Posted In
c,
erlang,
random
|
0
意見
|
