<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Erlang非业余研究 &#187; compile</title>
	<atom:link href="http://blog.yufeng.info/archives/tag/compile/feed" rel="self" type="application/rss+xml" />
	<link>http://blog.yufeng.info</link>
	<description>Erlang系统深度探索和应用</description>
	<lastBuildDate>Tue, 17 Jan 2012 06:05:54 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>leveldb ubuntu 11.04下编译失败问题</title>
		<link>http://blog.yufeng.info/archives/1319</link>
		<comments>http://blog.yufeng.info/archives/1319#comments</comments>
		<pubDate>Sun, 22 May 2011 08:39:21 +0000</pubDate>
		<dc:creator>Yu Feng</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[杂七杂八]]></category>
		<category><![CDATA[compile]]></category>
		<category><![CDATA[cstdatomic]]></category>
		<category><![CDATA[leveldb]]></category>
		<category><![CDATA[ubuntu]]></category>

		<guid isPermaLink="false">http://blog.yufeng.info/?p=1319</guid>
		<description><![CDATA[原创文章，转载请注明： 转载自Erlang非业余研究 本文链接地址: leveldb ubuntu 11.04下编译失败问题 我在最新的ubuntu11.04下编译leveldb的时候发现问题,但是在更早前的这个版本很正常： 我的编译环境: 头文件cstdatomic找不到, 简单的google下发现4.5的gcc这个头文件改名成atomic It seems that cstdatomic was renamed to atomic in newer GCC versions. Replacing cstdatomic include with atomic include in the header worked for me. 解决方法很简单： 修改./port/port_posix.h:14 成 现在再实验下： bingo, 玩得开心! Post Footer automatically generated by wp-posturl plugin for wordpress.]]></description>
			<content:encoded><![CDATA[<div style="margin-top: 15px; font-style: italic">
<p><strong>原创文章，转载请注明：</strong> 转载自<a href="http://blog.yufeng.info/">Erlang非业余研究</a></p>
<p><strong>本文链接地址:</strong> <a href="http://blog.yufeng.info/archives/1319">leveldb ubuntu 11.04下编译失败问题</a></p>
</div>
<p>我在最新的ubuntu11.04下编译leveldb的时候发现问题,但是在更早前的这个版本很正常：</p>
<pre class="brush: bash; title: ; notranslate">
yufeng@yufeng-laptop:/usr/src/leveldb$ make
g++ -c -DLEVELDB_PLATFORM_POSIX -I. -I./include -std=c++0x -g2 db/db_bench.cc -o db/db_bench.o
In file included from ./port/port.h:14:0,
                 from ./util/coding.h:17,
                 from ./db/dbformat.h:13,
                 from ./db/db_impl.h:9,
                 from db/db_bench.cc:8:
./port/port_posix.h:14:22: fatal error: cstdatomic: 没有那个文件或目录
compilation terminated.
make: *** [db/db_bench.o] 错误 1
</pre>
<p><span id="more-1319"></span><br />
我的编译环境:</p>
<pre class="brush: bash; title: ; notranslate">
$ cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=11.04
DISTRIB_CODENAME=natty
DISTRIB_DESCRIPTION=&quot;Ubuntu 11.04&quot;

$ gcc -v
Using built-in specs.
COLLECT_GCC=/usr/bin/gcc-4.5.real
COLLECT_LTO_WRAPPER=/usr/lib/x86_64-linux-gnu/gcc/x86_64-linux-gnu/4.5.2/lto-wrapper
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu/Linaro 4.5.2-8ubuntu4' --with-bugurl=file:///usr/share/doc/gcc-4.5/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.5 --enable-shared --enable-multiarch --with-multiarch-defaults=x86_64-linux-gnu --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib/x86_64-linux-gnu --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.5 --libdir=/usr/lib/x86_64-linux-gnu --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-plugin --enable-gold --enable-ld=default --with-plugin-ld=ld.gold --enable-objc-gc --disable-werror --with-arch-32=i686 --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 4.5.2 (Ubuntu/Linaro 4.5.2-8ubuntu4) 
</pre>
<p>头文件cstdatomic找不到, 简单的google下发现4.5的gcc这个头文件改名成atomic</p>
<blockquote><p>It seems that cstdatomic was renamed to atomic in newer GCC versions.<br />
Replacing cstdatomic include with atomic include in the header worked<br />
for me.</p></blockquote>
<p>解决方法很简单：</p>
<p>修改./port/port_posix.h:14 成
<pre class="brush: cpp; title: ; notranslate">#include &lt;atomic&gt;</pre>
<p>现在再实验下：</p>
<pre class="brush: bash; title: ; notranslate">
$ make
...

#跑测试案例
$ make check  
</pre>
<p>bingo, 玩得开心!</p>
<div style="margin-top: 0; margin-bottom: 15px; color: #888888; font-size: 80%; font-style: italic">
<p>Post Footer automatically generated by <a href="http://easwy.com/blog/wordpress/wp-posturl/" style="color: #8888FF; text-decoration: underline;">wp-posturl plugin</a> for wordpress.</p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://blog.yufeng.info/archives/1319/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Systemtap的另类用法</title>
		<link>http://blog.yufeng.info/archives/826</link>
		<comments>http://blog.yufeng.info/archives/826#comments</comments>
		<pubDate>Wed, 10 Nov 2010 06:29:29 +0000</pubDate>
		<dc:creator>Yu Feng</dc:creator>
				<category><![CDATA[Erlang探索]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[工具介绍]]></category>
		<category><![CDATA[compile]]></category>
		<category><![CDATA[module]]></category>
		<category><![CDATA[systemtap]]></category>
		<category><![CDATA[头文件]]></category>
		<category><![CDATA[编译]]></category>

		<guid isPermaLink="false">http://blog.yufeng.info/?p=826</guid>
		<description><![CDATA[原创文章，转载请注明： 转载自Erlang非业余研究 本文链接地址: Systemtap的另类用法 通常我们在做内核编程的时候，会用到内核的数据结构，比如说textsearch提供了几种算法用于支付串查找。在用于正式的项目前，我们会希望考察下他的用法以及想体验下。最通常的做法是自己写个module,写个makefile,编译，运行，然后去dmesg里面看printk的结果。这个过程没啥问题，就是太罗嗦。好了，现在我们有更方便的方法了：systemtap. Systemtap是个脚本，先翻译成c kernel模块代码，然后编译，插入到内核运行，同时提供最基本的内核和应用模块的通讯管道，在应用模块这里收集信息。 它还支持guru模式，让用户直接插入c代码。 这样我们就可以利用stap的这一特性来做我们的实验。 底下我们来演示下： cool吧！ 把c语言当脚本编写啦。 但是这个stap有个缺点，就是头文件必须是内核include路径里面的，如果我们用到了其他头文件，编译的时候就出错。 这个问题挺烦人的，但是我们有探索精神，不怕的，我们来crack下吧 到现在为止 stap是crack过的. 我们再来实验下吧!首先把我们的头文件所在的路径通知到systemtap，它会在让编译模块的时候加上我们的头文件路径。 哈哈，成功了。 大家可以这样的方式用stap写很多好玩的东西，祝玩的开心。 Post Footer automatically generated by wp-posturl plugin for wordpress.]]></description>
			<content:encoded><![CDATA[<div style="margin-top: 15px; font-style: italic">
<p><strong>原创文章，转载请注明：</strong> 转载自<a href="http://blog.yufeng.info/">Erlang非业余研究</a></p>
<p><strong>本文链接地址:</strong> <a href="http://blog.yufeng.info/archives/826">Systemtap的另类用法</a></p>
</div>
<p>通常我们在做内核编程的时候，会用到内核的数据结构，比如说textsearch提供了几种算法用于支付串查找。在用于正式的项目前，我们会希望考察下他的用法以及想体验下。最通常的做法是自己写个module,写个makefile,编译，运行，然后去dmesg里面看printk的结果。这个过程没啥问题，就是太罗嗦。好了，现在我们有更方便的方法了：systemtap.</p>
<p>Systemtap是个脚本，先翻译成c kernel模块代码，然后编译，插入到内核运行，同时提供最基本的内核和应用模块的通讯管道，在应用模块这里收集信息。 它还支持guru模式，让用户直接插入c代码。 这样我们就可以利用stap的这一特性来做我们的实验。<br />
<span id="more-826"></span><br />
底下我们来演示下：</p>
<pre class="brush: bash; title: ; notranslate">
# cat ts.stp
%{
#include &lt;linux/textsearch.h&gt;
%}
function test_textsearch:long (algo:string) %{ /* pure */ /* unprivileged */
struct ts_config* ts;
struct ts_state state;

ts = textsearch_prepare(THIS-&gt;algo, &quot;world&quot;, 5, GFP_KERNEL, TS_AUTOLOAD);
if(IS_ERR(ts)) goto err;
_stp_printf(&quot;%s\n&quot;, &quot;prepare ok!&quot;);
if(UINT_MAX==textsearch_find_continuous(ts, &amp;state, &quot;hello world&quot;, 11)) goto err;
_stp_printf(&quot;%s\n&quot;, &quot;find ok!&quot;);
textsearch_destroy(ts);
THIS-&gt;__retvalue = 0;
return;
err:
_stp_printf(&quot;%s\n&quot;, &quot;init error!&quot;);
THIS-&gt;__retvalue = -1;
return;
%}

probe begin
{
printf(&quot;result:%d\n&quot;, test_textsearch(@1));
exit();
}

%%请注意我们上面用到了 _stp_printf，代替printk, 这个是stap的runtime的基础服务。

# stap -gu ts.stp bm %%我们用的是BM算法
prepare ok!
find ok!
result:0
</pre>
<p>cool吧！ 把c语言当脚本编写啦。</p>
<p>但是这个stap有个缺点，就是头文件必须是内核include路径里面的，如果我们用到了其他头文件，编译的时候就出错。</p>
<pre class="brush: bash; title: ; notranslate">
# touch xyz.h #建个空的头文件
# diff -u ts.stp ts1.stp
--- ts.stp      2010-11-08 12:04:54.000000000 +0800
+++ ts1.stp     2010-11-10 14:19:47.000000000 +0800
@@ -1,5 +1,6 @@
 %{
 #include &lt;linux/textsearch.h&gt;
+#include &quot;xyz.h&quot;
 %}

# stap -gu ts1.stp bm
/tmp/stapKuLo9R/stap_90d03f83d4d4a8efa7b721a6ff0093fe_2503.c:169:17: error: xyz.h: No such file or directory
make[1]: *** [/tmp/stapKuLo9R/stap_90d03f83d4d4a8efa7b721a6ff0093fe_2503.o] Error 1
make: *** [_module_/tmp/stapKuLo9R] Error 2
Pass 4: compilation failed.  Try again with another '--vp 0001' option.
</pre>
<p>这个问题挺烦人的，但是我们有探索精神，不怕的，我们来crack下吧</p>
<pre class="brush: bash; title: ; notranslate">
# diff systemtap-1.3/buildrun.cxx systemtap-1.3.patched/buildrun.cxx
235a236,238
&gt;
&gt;   o &lt;&lt; &quot;EXTRA_CFLAGS += $(STAP_CFLAGS)&quot; &lt;&lt; endl;
&gt;
237a241
&gt;
# ./configure --prefix=/usr &amp;&amp; make &amp;&amp; make install
</pre>
<p>到现在为止 stap是crack过的. 我们再来实验下吧!首先把我们的头文件所在的路径通知到systemtap，它会在让编译模块的时候加上我们的头文件路径。</p>
<pre class="brush: bash; title: ; notranslate">
# export STAP_CFLAGS=&quot;-I`pwd`&quot;
# printenv STAP_CFLAGS
-I/home/wentong

# stap -gu ts1.stp bm
prepare ok!
find ok!
result:0
</pre>
<p>哈哈，成功了。</p>
<p>大家可以这样的方式用stap写很多好玩的东西，祝玩的开心。</p>
<div style="margin-top: 0; margin-bottom: 15px; color: #888888; font-size: 80%; font-style: italic">
<p>Post Footer automatically generated by <a href="http://easwy.com/blog/wordpress/wp-posturl/" style="color: #8888FF; text-decoration: underline;">wp-posturl plugin</a> for wordpress.</p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://blog.yufeng.info/archives/826/feed</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
		<item>
		<title>如何在TILEPro64多核心板卡上编译和运行Erlang</title>
		<link>http://blog.yufeng.info/archives/791</link>
		<comments>http://blog.yufeng.info/archives/791#comments</comments>
		<pubDate>Tue, 02 Nov 2010 02:25:35 +0000</pubDate>
		<dc:creator>Yu Feng</dc:creator>
				<category><![CDATA[Erlang探索]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[工具介绍]]></category>
		<category><![CDATA[64]]></category>
		<category><![CDATA[compile]]></category>
		<category><![CDATA[install]]></category>
		<category><![CDATA[kernel]]></category>
		<category><![CDATA[otp]]></category>
		<category><![CDATA[Tilera]]></category>
		<category><![CDATA[并发，并行]]></category>

		<guid isPermaLink="false">http://blog.yufeng.info/?p=791</guid>
		<description><![CDATA[原创文章，转载请注明： 转载自Erlang非业余研究 本文链接地址: 如何在TILEPro64多核心板卡上编译和运行Erlang 参考文章： 1. https://groups.google.com/group/erlang-programming/msg/2d61b1083a10a7b6 2. http://erlang.2086793.n4.nabble.com/How-to-Cross-compile-Erlang-OTP-R13B04-for-TileraPro64-td2119304.html 美国Tilera公司的众核服务器，单颗内核包含64颗CPU。硬件架构图： 卡长这样的： Erlang已经可以在这款CPU上成功运行，我们可以参考Ulf Wiger在Multicore ☺ Message-passing Concurrency 文档中关于Erlang在Tilera上的性能图. Erlang系统前2年就开始正式支持Tilera，一直用这个CPU来调整他的调度器，所以性能和基础的编译运行支持都很到位。 Linux内核2.6.36起就开始支持Tilera的CPU架构了，看起来前途不错。 最近 上海泛腾电子科技 开始在国内销售 Tilera机器， 我公司也得到一台样机，使得我有机会把玩下这个高科技！ 该测试机是PCI-e的形式，是单板机，直接安装在PC机或者是服务器里,好处是可以通过主机的VGA口接显示器直接调试。当然也可以作为智能网卡来使用。构成一个与Host的异构结构，通过PCI-e总线进行通讯。 还需要相应的配套SDK: 目前有TileraMDE-2.1.2.112814 和 TileraMDE-3.0.alpha3.116173 二个版本, 来负责和板卡的通信。 推荐用2.0的，好像不容易出问题。 废话少说，让我们开始享受64核心快乐旅程吧！ 好吧到此为止，我们在目标机器上/tmp/otp目录下有个完整的erlang系统。 我们开个console连接到板载的linux系统去： Bingo! 我们顺利的跑了数学计算，同时绑定调度器到CPU core上去了。接下来就可以按照平常那样进行Erlang并发编程了。 祝玩的开心！ Post Footer automatically generated by wp-posturl plugin for wordpress.]]></description>
			<content:encoded><![CDATA[<div style="margin-top: 15px; font-style: italic">
<p><strong>原创文章，转载请注明：</strong> 转载自<a href="http://blog.yufeng.info/">Erlang非业余研究</a></p>
<p><strong>本文链接地址:</strong> <a href="http://blog.yufeng.info/archives/791">如何在TILEPro64多核心板卡上编译和运行Erlang</a></p>
</div>
<p>参考文章：<br />
1. <a href="https://groups.google.com/group/erlang-programming/msg/2d61b1083a10a7b6">https://groups.google.com/group/erlang-programming/msg/2d61b1083a10a7b6</a></p>
<p>2. <a href="http://erlang.2086793.n4.nabble.com/How-to-Cross-compile-Erlang-OTP-R13B04-for-TileraPro64-td2119304.html">http://erlang.2086793.n4.nabble.com/How-to-Cross-compile-Erlang-OTP-R13B04-for-TileraPro64-td2119304.html</a></p>
<p>美国Tilera公司的众核服务器，单颗内核包含64颗CPU。硬件架构图：<br />
<a href="http://blog.yufeng.info/wp-content/uploads/2010/11/Tile_Processor_Hardware_Architecture.jpg"><img src="http://blog.yufeng.info/wp-content/uploads/2010/11/Tile_Processor_Hardware_Architecture.jpg" alt="" title="Tile_Processor_Hardware_Architecture" width="792" height="439" class="alignnone size-full wp-image-806" /></a><br />
卡长这样的：<br />
<a href="http://blog.yufeng.info/wp-content/uploads/2010/11/tilera_board.jpg"><img src="http://blog.yufeng.info/wp-content/uploads/2010/11/tilera_board.jpg" alt="" title="tilera_board" width="208" height="148" class="alignnone size-full wp-image-820" /></a><br />
Erlang已经可以在这款CPU上成功运行，我们可以参考Ulf Wiger在Multicore ☺ Message-passing Concurrency 文档中关于Erlang在Tilera上的性能图.<br />
<a href="http://blog.yufeng.info/wp-content/uploads/2010/11/multi_core_message_passing_concurrency_erlang.jpg"><img src="http://blog.yufeng.info/wp-content/uploads/2010/11/multi_core_message_passing_concurrency_erlang.jpg" alt="" title="multi_core_message_passing_concurrency_erlang" width="627" height="405" class="alignnone size-full wp-image-798" /></a></p>
<p>Erlang系统前2年就开始正式支持Tilera，一直用这个CPU来调整他的调度器，所以性能和基础的编译运行支持都很到位。</p>
<p>Linux内核2.6.36起就开始支持Tilera的CPU架构了，看起来前途不错。</p>
<p>最近 上海泛腾电子科技 开始在国内销售 Tilera机器， 我公司也得到一台样机，使得我有机会把玩下这个高科技！</p>
<p>该测试机是PCI-e的形式，是单板机，直接安装在PC机或者是服务器里,好处是可以通过主机的VGA口接显示器直接调试。当然也可以作为智能网卡来使用。构成一个与Host的异构结构，通过PCI-e总线进行通讯。</p>
<p>还需要相应的配套SDK: 目前有TileraMDE-2.1.2.112814 和 TileraMDE-3.0.alpha3.116173 二个版本, 来负责和板卡的通信。 推荐用2.0的，好像不容易出问题。</p>
<p>废话少说，让我们开始享受64核心快乐旅程吧！<br />
<span id="more-791"></span></p>
<pre class="brush: bash; title: ; notranslate">
# wget http://www.erlang.org/download/otp_src_R13B03.tar.gz  %%R13B04后otp_build变了好像有点问题，编译不过去。
# tar xzf otp_src_R13B03.tar.gz
# cd otp_src_R13B03
%%由于R13B03有个小小的bug会导致segment fault,我们需要对erl_misc_utils.c打个patch,以下是要打patch的地方:
# diff -Nau otp_src_R13B04/erts/lib_src/common/erl_misc_utils.c{~,}
--- otp_src_R13B04/erts/lib_src/common/erl_misc_utils.c~
2009-11-20 14:32:23.000000000 +0100
+++ otp_src_R13B04/erts/lib_src/common/erl_misc_utils.c 2010-03-29
15:53:28.000000000 +0200
@@ -373,8 +373,8 @@
        return 0;
     memcpy((void *) topology,
           (void *) cpuinfo-&gt;topology,
-          cpuinfo-&gt;configured*sizeof(erts_cpu_topology_t));
-    return cpuinfo-&gt;configured;
+          cpuinfo-&gt;topology_size*sizeof(erts_cpu_topology_t));
+    return cpuinfo-&gt;topology_size;
 }
%%源码算是准备完毕了 

%%开始编译前的环境准备
# export ERL_TOP=`pwd`
# eval `./otp_build env_cross $ERL_TOP/xcomp/erl-xcomp-TileraMDE2.0-tilepro.conf`
# export TILERA_ROOT=/root/TileraMDE-2.1.2.112814/tilepro/  %%这个最好用2.x版本的
# export PATH=$TILERA_ROOT/bin:$PATH
# tile-monitor --pci -- uname -a  %%验证板卡确实可用
Linux localhost 2.6.26.7-MDE-2.1.2.112814 #1 SMP Wed Sep 1 00:05:06 EDT 2010 tile GNU/Linux

%%开始交叉编译
# ./otp_build configure
# touch lib/crypto/SKIP &amp;&amp;  touch lib/ssl/SKIP &amp;&amp; touch lib/ssh/SKIP   %%这几个模块用到了openssl, 编译不过去，忽略掉
# ./otp_build boot -a
# ./otp_build release -a /tmp/otp %%安装到/tmp/otp目录去

%%如果一切顺利，到这时候就编译完毕了。

%%我们开始收获成果。

# cd /tmp/otp
# ./Install `pwd`
#  tile-monitor --pci --here -- bin/erl  %%没出错的话，就说明我们成功了。

%%当然我们可以把otp系统上载到板卡去，方便日后使用
# $TILERA_ROOT/bin/tile-monitor --pci  --upload /tmp/otp /tmp/otp --quit   %% 放在板卡的/tmp/otp目录下

%%我们还可以定义个命令别名，方便我们执行命令
# tile_erl=&quot;$TILERA_ROOT/bin/tile-monitor --pci --resume --tunnel 2023 23  --env HOME=/tmp  --tiles - all ^0 - -- /tmp/otp/bin/erl&quot;
# $tile_erl +sct L10-18,1-9,19-55,57,58,61c1-55,57,58,61 +sbt db   -noshell +S 58 -s init stop
</pre>
<p>好吧到此为止，我们在目标机器上/tmp/otp目录下有个完整的erlang系统。</p>
<p>我们开个console连接到板载的linux系统去：</p>
<pre class="brush: bash; title: ; notranslate">
[root@client otp_src_R13B03]# /root/TileraMDE-2.1.2.112814/tilepro/bin/tile-console
tile-console: Assuming '--pci'.
Connecting to /dev/ttyS0, speed 115200
 Escape character: Ctrl-\ (ASCII 28, FS): enabled
Type the escape character followed by C to get back,
or followed by ? to see other options.
----------------------------------------------------
# uname -a
Linux localhost 2.6.26.7-MDE-2.1.2.112814 #1 SMP Wed Sep 1 00:05:06 EDT 2010 tile GNU/Linux

# cd /tmp/otp
%%我们跑个erlang程序&lt;em&gt;64核心并行&lt;/em&gt;进行数学计算
%% 代码在这里下载 http://shootout.alioth.debian.org/u32/program.php?test=spectralnorm&amp;lang=hipe&amp;id=2
#cat &gt; spectralnorm.erl
%   The Computer Language Benchmarks Game
%   http://shootout.alioth.debian.org/
%   contributed by Fredrik Svahn

-module(spectralnorm).
-export([main/1]).
-compile( [ inline, { inline_size, 1000 } ] ).

main([Arg]) -&gt;
    register(server, self()),
    N = list_to_integer(Arg),
    {U, V} = power_method(N, 10, erlang:make_tuple(N, 1), []),
    io:format(&quot;~.9f\n&quot;, [ eigen(N, U, V, 0, 0) ]),
    erlang:halt(0).

% eigenvalue of V
eigen(0, _, _, VBV, VV) when VV /= 0 -&gt; math:sqrt(VBV / VV);

eigen(I, U, V, VBV, VV) when I /= 0 -&gt;
    VI = element(I, V),
    eigen(I-1, U, V, VBV + element(I, U)*VI, VV + VI*VI).

% 2I steps of the power method
power_method(_, 0, A, B) -&gt; {A, B};
power_method(N, I, A, _B) -&gt;
    V = atav(N, A),
    U = atav(N, V),
    power_method(N, I-1, U, V).

% return element i,j of infinite matrix A
a(II,JJ) -&gt; 1/((II+JJ-2)*(II-1+JJ)/2+II).

% multiply vector v by matrix A
av(N, V) -&gt; pmap(N, fun(Begin, End) -&gt; av(N, Begin, End, V) end).

av(N, Begin, End, V) -&gt; server ! { self(), [ avloop(N, I, V, 0.0) || I &lt;- lists:seq(Begin, End) ]}.

avloop(0, _, _, X) -&gt;  X;
avloop(J, I, V, X) -&gt;  avloop(J-1, I, V, X + a(I, J)*element(J, V) ).

% multiply vector v by matrix A transposed
atv(N, V) -&gt; pmap(N, fun(Begin, End)-&gt; atv(N, Begin, End, V) end).

atv(N, Begin, End, V) -&gt; server ! { self(), [ atvloop(N, I, V, 0.0) || I &lt;- lists:seq(Begin, End) ]}.

atvloop(0, _, _, X) -&gt; X;
atvloop(J, I, V, X) -&gt; atvloop(J-1, I, V, X + a(J, I)*element(J, V) ).

% multiply vector v by matrix A and then by matrix A transposed
atav(N, V) -&gt; atv(N, av(N, V)).

%Helper function for multicore
pmap(N, F) -&gt;
    Chunks = chunks(0, erlang:system_info(logical_processors), N, []),
    Pids = [spawn(fun()-&gt; F(Begin, End) end) || {Begin, End} &lt;- Chunks],
    Res = [ receive {Pid, X} -&gt; X end || Pid &lt;- Pids],
    list_to_tuple(lists:flatten(Res)).

chunks(I, P, N, A) when I == P-1 -&gt; lists:reverse([{I*(N div P)+1, N} | A ]);
chunks(I, P, N, A) -&gt; chunks(I+1, P, N, [{ I*(N div P)+1, (I+1)*(N div P)} | A ]).

CTRL+D

# bin/erlc spectralnorm.erl
# time bin/erl -noshell -run spectralnorm  main 500  -s init stop
1.274224116
real    0m 16.90s
user    1m 16.07s
sys     0m 0.79s
# bin/erl  +sct L10-18,1-9,19-55,57,58,61c1-55,57,58,61 +sbt db   -noshell +S 58 -eval 'io:format(&quot;schedulers: ~p~n&quot;1)' -s init stop
schedulers: 58
</pre>
<p>Bingo! 我们顺利的跑了数学计算，同时绑定调度器到CPU core上去了。接下来就可以按照平常那样进行Erlang并发编程了。</p>
<p>祝玩的开心！</p>
<div style="margin-top: 0; margin-bottom: 15px; color: #888888; font-size: 80%; font-style: italic">
<p>Post Footer automatically generated by <a href="http://easwy.com/blog/wordpress/wp-posturl/" style="color: #8888FF; text-decoration: underline;">wp-posturl plugin</a> for wordpress.</p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://blog.yufeng.info/archives/791/feed</wfw:commentRss>
		<slash:comments>20</slash:comments>
		</item>
		<item>
		<title>escript的高级特性</title>
		<link>http://blog.yufeng.info/archives/153</link>
		<comments>http://blog.yufeng.info/archives/153#comments</comments>
		<pubDate>Tue, 24 Nov 2009 21:45:55 +0000</pubDate>
		<dc:creator>Yu Feng</dc:creator>
				<category><![CDATA[Erlang探索]]></category>
		<category><![CDATA[compile]]></category>
		<category><![CDATA[debug]]></category>
		<category><![CDATA[escript]]></category>
		<category><![CDATA[mode]]></category>
		<category><![CDATA[zip]]></category>

		<guid isPermaLink="false">http://blog.yufeng.info/?p=153</guid>
		<description><![CDATA[原创文章，转载请注明： 转载自Erlang非业余研究 本文链接地址: escript的高级特性 escript Erlang scripting support, 可以让erl模块转身变成unix script来使用，大大方便用户，具体的使用参看otp文档。我这里要演示的是些比较被忽视的高级特性: 首先crack erts/etc/common/escript.c:33 static int debug = 1; 让之显示调用参数。 CTRL+D [color=red]erl +B -boot start_clean -noshell -smp enable -sname factorial -mnesia debug verbose -run escript start -extra ./factorial 10[/color] factorial 10 = 3628800 特性1： 摘抄文档。。。 On the third line (or second line depending on the presence of [...]]]></description>
			<content:encoded><![CDATA[<div style="margin-top: 15px; font-style: italic">
<p><strong>原创文章，转载请注明：</strong> 转载自<a href="http://blog.yufeng.info/">Erlang非业余研究</a></p>
<p><strong>本文链接地址:</strong> <a href="http://blog.yufeng.info/archives/153">escript的高级特性</a></p>
</div>
<p>escript Erlang scripting support, 可以让erl模块转身变成unix script来使用，大大方便用户，具体的使用参看otp文档。我这里要演示的是些比较被忽视的高级特性:</p>
<p>首先crack erts/etc/common/escript.c:33  static int debug = 1; 让之显示调用参数。</p>
<pre class="brush: bash; title: ; notranslate">root@nd-desktop:~# cat &amp;gt;factorial</pre>
<pre class="brush: erlang; title: ; notranslate">
[color=red]#!/usr/bin/env escript
%% -*- erlang -*-
%%! -smp enable -sname factorial -mnesia debug verbose[/color]
main([String]) -&gt;
try
N = list_to_integer(String),
F = fac(N),
io:format(&quot;factorial ~w = ~w\n&quot;, [N,F])
catch
_:_ -&gt;
usage()
end;
main(_) -&gt;
usage().

usage() -&gt;
io:format(&quot;usage: factorial integer\n&quot;),
halt(1).

fac(0) -&gt; 1;
fac(N) -&gt; N * fac(N-1).
</pre>
<p>CTRL+D</p>
<pre class="brush: bash; title: ; notranslate">
root@nd-desktop:~# chmod +x factorial
root@nd-desktop:~#　./factorial  10
</pre>
<p>[color=red]erl +B -boot start_clean -noshell -smp enable -sname factorial -mnesia debug verbose -run escript start -extra ./factorial 10[/color]<br />
factorial 10 = 3628800</p>
<p><strong>特性1：</strong></p>
<p>摘抄文档。。。<br />
On the third line (or second line depending on the presence of the Emacs directive), it is possible to give arguments to the emulator, such as</p>
<p>%%! -smp enable -sname factorial -mnesia debug verbose</p>
<p>Such an argument line must start with %%! and the rest of the line will interpreted as arguments to the emulator.</p>
<p>我们可以看到　这些选项被传递给了 erl</p>
<p><strong>特性2： </strong><br />
-mode(compile).</p>
<p>这个选项是在escript.erl这个模块处理的。默认情况下 escript是被解释执行的，如果你的脚本很复杂，那么效率估计会是瓶颈。这种情况下， 你可以通过这个选项来让escript来先编译你的模块成opcode, 在vm里面运行。</p>
<p><strong>特性3：</strong><br />
-d 选项 用来调试script的<br />
-c  编译执行<br />
-i  解释执行<br />
-s  只检查不执行<br />
root@nd-desktop:~#　escript -d ./factorial  10<br />
我们就可以看到 调试界面如下图<br />
<a href="http://blog.yufeng.info/wp-content/uploads/2009/11/escript_debug.PNG"><img class="alignnone size-medium wp-image-154" title="escript_debug" src="http://blog.yufeng.info/wp-content/uploads/2009/11/escript_debug-275x300.PNG" alt="escript_debug" width="275" height="300" /></a></p>
<p><strong>特性4：</strong><br />
可以把一个beam文件作为script</p>
<pre class="brush: bash; title: ; notranslate">
root@nd-desktop:/usr/src# cat hello.erl
</pre>
<pre class="brush: erlang; title: ; notranslate">
-module(hello).
-export([start/0,main/1]).

main(_)-&gt;
start().

start()-&gt;
io:format(&quot;hello world~n&quot;,[]).
</pre>
<pre class="brush: bash; title: ; notranslate">
root@nd-desktop:/usr/src# erlc hello.erl
root@nd-desktop:/usr/src# cat &amp;gt;hello
</pre>
<pre class="brush: erlang; title: ; notranslate">
#!/usr/bin/env escript
%% -*- erlang -*-
%%! -smp enable -sname factorial -mnesia debug verbose
</pre>
<p>CTRL+D</p>
<pre class="brush: bash; title: ; notranslate">
root@nd-desktop:/usr/src# cat hello.beam &amp;gt;&amp;gt;hello
root@nd-desktop:/usr/src# chmod +x hello
root@nd-desktop:/usr/src# ./hello
hello world
</pre>
<p><strong>特性5:</strong><br />
可以把一个zip文件作为script</p>
<pre class="brush: bash; title: ; notranslate">
root@nd-desktop:/usr/src# cat hello.erl
</pre>
<pre class="brush: erlang; title: ; notranslate">
-module(hello).
-export([start/0,main/1]).

main(_)-&gt;
start().

start()-&gt;
io:format(&quot;hello world, fac(10)=~w ~n&quot;,[fac:fac(10)]).</pre>
<pre class="brush: bash; title: ; notranslate">
root@nd-desktop:/usr/src# cat fac.erl
</pre>
<pre class="brush: erlang; title: ; notranslate">
-module(fac).
-export([fac/1]).

fac(0) -&gt;
1;
fac(N) -&gt; N * fac(N-1).</pre>
<pre class="brush: bash; title: ; notranslate">
root@nd-desktop:/usr/src# erlc *.erl
root@nd-desktop:/usr/src# erl
Erlang R13B03 (erts-5.7.4)
[smp:2:2] [rq:2] [async-threads:0] [hipe] [kernel-poll:false]

Eshell V5.7.4  (abort with ^G)
1&amp;gt; zip:zip(&quot;hello.zip&quot;, [&quot;hello.beam&quot;, &quot;fac.beam&quot;]).
{ok,&quot;hello.zip&quot;}
2&amp;gt;
</pre>
<pre class="brush: bash; title: ; notranslate">
root@nd-desktop:/usr/src# cat &amp;gt;hello
</pre>
<pre class="brush: erlang; title: ; notranslate">
#!/usr/bin/env escript
%% -*- erlang -*-
%%! -smp enable -sname factorial -mnesia debug verbose -escript main hello
</pre>
<p>CTRL+D</p>
<pre class="brush: bash; title: ; notranslate">
root@nd-desktop:/usr/src# cat hello.zip &amp;gt;&amp;gt;hello
root@nd-desktop:/usr/src# chmod +x hello
root@nd-desktop:/usr/src# ./hello
hello world, fac(10)=3628800
</pre>
<p><strong>特性6：</strong><br />
在独立的包里面 把escript伪装成我们的应用程序</p>
<pre class="brush: bash; title: ; notranslate">
root@nd-desktop:/usr/src# cat &amp;gt;hello.escript
</pre>
<pre class="brush: erlang; title: ; notranslate">
-module(hello).
-export([start/0,main/1]).

main(_)-&gt;
start().

start()-&gt;
io:format(&quot;hello world~n&quot;,[]).
</pre>
<p>CTRL+D</p>
<pre class="brush: bash; title: ; notranslate">
root@nd-desktop:/usr/src#  cp `which escript` hello
root@nd-desktop:/usr/src# ./hello
hello world
</pre>
<p>规则是 escript 改名成xxxx 执行xxxx的时候 实际上要读取的脚本是 xxxx.escript</p>
<p><strong>综述： escript是很强大的 未来的erlang standalone全靠它。</strong></p>
<div style="margin-top: 0; margin-bottom: 15px; color: #888888; font-size: 80%; font-style: italic">
<p>Post Footer automatically generated by <a href="http://easwy.com/blog/wordpress/wp-posturl/" style="color: #8888FF; text-decoration: underline;">wp-posturl plugin</a> for wordpress.</p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://blog.yufeng.info/archives/153/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>

