아래 테스트 코드는 문제가 있었습니다. 왜냐하면 GCC 최적화 옵션에 대해서 명확히 이해를 못하고 사용했기 때문입니다. 그래서 잘못된 지식을 전하는 것을 우려해 그냥 내용만 훑어보시되 “Adobe Alchemy 수행속도 테스트와 깊이 이해하기”글을 덧붙여 읽어주시길 바랍니다. 제가 잘못된 내용을 적었다면 지적해주셨으면 합니다. 그리고 실무에 썼거나 테스트를 해보신 분이라면 그에 대해 소개도 부탁드릴께요.

Alchemy는 C/C++ 코드를 AVM2(ActionScript 3 Virtual Machine) 환경에서 동작하도록 해주는 도구이다. Alchemy를 이용해 기존에 있는 C/C++ 코드를 Adobe AIR, Adobe Flex, Adobe Flash 프로젝트에서 직접 활용할 수 있는 SWF 또는 SWC를 만들어낼 수 있다. 이에 대한 더욱 자세한 사항은 본인이 게재한 “C/C++와 Flash 플랫폼과의 만남. Alchemy 1부” 를 참고하기 바란다.

 

이 글은 Alchemy를 이용해 만들어진 SWC를 이용했을 때와 순수 ActionScript 3.0으로만 코딩했을 때 수행속도 차이를 비교해보는 것을 목적으로 한다.

 

Alchemy 속도 테스트

 

과연 Alchemy를 이용해서 C언어를 SWC로 변환한 코드의 수행속도에 진전이 있을까? 아래 c코드와 ActionScript 3.0 코드는 이를 테스트할 수 있도록 한다. c언어와 ActionScript 3.0에서 동일하게 ”sin( 0.332 ) + cos( 0.123 ) + tan(0.333) * log(3)” 식을 1백만번 반복한다.

 

컴파일하고 수행하는 방법은 “C/C++와 Flash 플랫폼과의 만남. Alchemy 1부”를 참고한다.

1. speedtest.c

#include <math.h>
#include "AS3.h"

static AS3_Val c_speed_test(void* self, AS3_Val args)
{
    int i;
    double result;
    for( i=0; i < 1000000; i++ )
    {
        result = sin( 0.332 ) + cos( 0.123 ) + tan(0.333) * log(3);
    }
    return AS3_Number(result);
}

int main()
{
    AS3_Val method = AS3_Function( NULL, c_speed_test );
    AS3_Val result = AS3_Object( "c_speed_test: AS3ValType", method );
    AS3_Release( method );
    AS3_LibInit( result );
    return 0;
}

 

2. AlchemySpeedTest.as

package {
    import cmodule.speedtest.CLibInit;

    import flash.display.Sprite;
    import flash.display.StageAlign;
    import flash.display.StageScaleMode;
    import flash.text.TextField;
    import flash.text.TextFieldAutoSize;
    import flash.text.TextFormat;
    import flash.utils.getTimer;

    public class AlchemySpeedTest extends Sprite
    {
        public function AlchemySpeedTest()
        {
            stage.scaleMode = StageScaleMode.NO_SCALE;
            stage.align = StageAlign.TOP_LEFT;

            var loader:CLibInit = new CLibInit();
            var lib:Object = loader.init();
            var startTime:Number;

            startTime = getTimer();
            var cResult:String = "c returned value : " + lib.c_speed_test(null) + " delay time(ms) : " + (getTimer()-startTime);

            startTime = getTimer();
            var asResult:String = "as3 returned value : " + as3_speed_test() + " delay time(ms) : " + (getTimer()-startTime);

            var textField:TextField = new TextField();
            textField.text = cResult + "\n" + asResult;
            textField.width = 500;
            textField.autoSize = TextFieldAutoSize.LEFT;
            textField.wordWrap = true;
            textField.defaultTextFormat = new TextFormat( null, 12 );
            addChild(textField);

        }
        public function as3_speed_test():Number
        {
            var i:int;
            var result:Number;
            //var sin:Function = Math.sin;
            //var cos:Function = Math.cos;
            for (i = 0; i < 1000000; i++)
            {
            result = Math.sin( 0.332 ) + Math.cos( 0.123 ) + Math.tan( 0.333 ) * Math.log(3);
            }
            return result;
        }
    }
}

 

speedtest.c를 아래처럼 Alchemy로 컴파일하고 만들어진 speedtest.swc를 AlchemySpeedTest.as와 함께 mxmlc로 컴파일 한다.

gcc speedtest.c –swc –o speedtest.swc
mxmlc.exe –library-path+=speedtest.swc –target-player=10.0.0 AlchemySpeedTest.as

아래는 위 프로그램을 시행한 결과이다.

c returned value : 1.6983678388082433 delay time(ms) : 559
as3 returned value : 1.6983678388082433 delay time(ms) : 694

이 결과는 의외의 결과이다. C와 ActionScript 3.0과 같은 수행속도를 보였기 때문이다. 하지만 이 결과는 C코드를 컴파일 할 때 최적화하지 않았기 때문이다. 아래처럼 –03 –Wall 옵션을 넣고 다시 수행해보자. -O3는 최적화 옵션이고 –Wall(또는 –W)는 모든 경고를 출력하도록 한다.

gcc speedtest.c –03 –Wall –swc –o speedtest.swc
mxmlc.exe –library-path+=speedtest.swc –target-player=10.0.0 AlchemySpeedTest.as

컴파일한 SWF파일을 실행한 결과는 다음과 같다.

c returned value : 1.6983678388082433 delay time(ms) : 1
as3 returned value : 1.6983678388082433 delay time(ms) : 601

 

결론

 

위 실험 결과를 통해 Alchemy를 이용해 C/C++의 수행속도를 잘 활용하면 좋다는 것을 알 수 있었다. 가령, ActionScript 3.0으로 구동 시에 많은 부하가 있을 가능성이 있는 부분을 C로 만들어 Alchemy를 통해 최적화된 SWC로 라이브러리화 해서 사용한다면 여러분의 Flash/Flex/AIR 애플리케이션의 속도를 크게 향상시킬 수 있다. 구체적으로 Audio/Video, 데이터 형식 변환, 데이터 조작, XML 분석 및 암호화 기능, 물리 시뮬레이션등이 들어가는 코드에서 포퍼먼스 향상을 기대할 수 있겠다.

아래는 Alchemy가 C/C++코드를 ActionScript 3.0 코드로 완벽하게 변경하는가에 대한 의견이다.

(글쓴이 의견)

어떤 분은 Alchemy로 SWF를 만들어준다고 해서 C/C++코드가 전부 ActionScript 3.0으로 변환될 것이다라는 생각을 가질 수 있다. 하지만 실험 결과만 가지고 볼 때 틀리다는 것을 유추할 수 있다. Alchemy는 C/C++ 코드를 AVM2 환경에서 동작하도록 만들되 ActionScript 3.0과 함께 사용할 수 있도록 만들어준다. 즉 C/C++를 적절하게 변경하고 ActionScript 3.0과 통신할 수 있는 통로구를 마련해주는 것이 Alchemy의 목적이다. 만약 ActionScript 3.0으로만 변경되는 것이라면 빠른 수행속도를 기대하기 어려울 것이다.

(양병규님 의견)

컴파일러에 대해서 조금 관심을 가져보시면 알 수 있을텐데요…
음… 뭐랄까…
그 최적화라는 것이 불필요한 일은 안하고 같은 기능이라면 더 빠른 기능으로 대치하고.. 그런일을 하는 것이 컴파일러의 최적화인데요..
제가 보기에는
for( i=0; i < 1000000; i++ )
{
result = sin( 0.332 ) + cos( 0.123 ) + tan(0.333) * log(3);
}
이 부분이.. 최적화를 하면 루프를 1000000번 돌지 않고 한방에 끝낼것같습니다. 최적화알고리즘중에서 루프문안에서의 내용이 반복을 해도 변화가 없는 경우에는 루프를 한방에 끝내도록 하는 알고리즘이 있습니다. 이 예가 그런 예일것 같은데요..

암튼.. ActionScript에는 그런 최적화가 없는데 이미 오랜 역사동안 만들어진 C/C++언어의 최적화 기술이 적용되면 분명히 나은 결과를 보일 것 으로 예상됩니다. ^^;(물론 코딩하는 사람의 실력이 좋을 수록 최적화의 효과가 떨어지겠지만)

그리고..
저는 아무리 봐도 C/C++로 코딩한 것이 결국 몽땅 ActionScript로 만들어지는 것이 맞는 것 같습니다. SWF에는 ActionScript 이 외에 다른 실행코드는 존재하지 않습니다. 최종적으로 만들어진 결과가 *.SWF(*.SWC)이지 않습니까? SWF File Format Specification Version 10 문서 278페이지를 다 훑어봐도 ActionScript 이외에는 실행코드가 없습니다. 머.. DLL을 임포트한다거나 별도의 실행코드용 외부 라이브러리가 있다거나… 그런건 전혀 없습니다.

malloc 함수 같은 경우의 예를 들어보면 ActionScript에는 malloc과 동일한 역할을 하는 어셈블명령은 없습니다. 하지만 ActionInitArray와 같이 긴 변수를 사용할 수 있는 명령으로 ‘구현’은 할 수 있을겁니다. 아마도 그런 방법으로 구현되지 않았나싶습니다.

어쨋든 Alchemy는 C/C++을 100% ActionScript로 변환해 주는게 맞고.. 함수사용, 변수사용, 최적화, 수학함수의 구현, 각종 기초 알고리즘등 기초적인 부분에서 훨씬 우월하기 때문에 좋은 효과를 나타내고 있는 것으로 생각됩니다.

시간이 나면 Alchemy에서 만들어진 SWF 파일을 분석해 보면 아주 좋은 공부가 될것같습니다. ^^;

Alchemy가 유용한 것은 C/C++ 코드를 ActionScript 3.0와 함께 쉽게 사용할 수 있게끔 해주는 것과 C/C++자체가 가지는 빠른 수행속도를 Flash 컨텐츠에서 이용할 수 있는 것으로 생각한다. Alchemy가 앞으로 사용 편의성 향상과 여러 환경에서 문제없이 개발할 수 있도록 개선된다면 Adobe RIA기술이 한 단계 업그레이드 될 것이라 생각한다.

 

한가지 주의할 사항은 전부 C/C++로 만드는 것은 좋지 못하다. Alchemy를 적용하기에 앞서 본문에서 실험한 것과 같은 방법으로 여러가지 수행 테스트를 해보고 순수하게 ActionScript 3.0으로 한 것보다 큰 포퍼먼스를 기대할 수 있다고 판단했을 때 적용하는 것이 좋다. 때로는 어떤 코드냐에 따라 별로 큰 차이가 없을 수 있기 때문이다.

국내에 Alchemy를 응용한 많은 예제와 애플리케이션들이 나오길 바란다.

 

참고할 사이트

 

+ Recent posts