<?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>编译点滴 &#187; 运行时技术</title>
	<atom:link href="http://www.lingcc.com/tag/%e8%bf%90%e8%a1%8c%e6%97%b6%e6%8a%80%e6%9c%af/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.lingcc.com</link>
	<description>编译器、虚拟机、程序设计语言、体系结构、软件调试、操作系统等等</description>
	<lastBuildDate>Sat, 04 Feb 2012 06:56:05 +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>调用栈-你还记得吗？</title>
		<link>http://www.lingcc.com/2010/09/27/11251/</link>
		<comments>http://www.lingcc.com/2010/09/27/11251/#comments</comments>
		<pubDate>Sun, 26 Sep 2010 16:14:34 +0000</pubDate>
		<dc:creator>erlv</dc:creator>
				<category><![CDATA[编译技术]]></category>
		<category><![CDATA[运行时技术]]></category>
		<category><![CDATA[传参]]></category>
		<category><![CDATA[调用栈]]></category>
		<category><![CDATA[面试题]]></category>

		<guid isPermaLink="false">http://www.lingcc.com/?p=11251</guid>
		<description><![CDATA[今天面试某公司，很想拿到offer的一家，结果因为一道自己应该会，却没能很好答上来的面试题被刷，很可惜。不过，当时的表现也太过浮躁，自己太急于求成了，痛定思痛，是时候好好反思一下这道题，再深入学习一下这背后的知识。面试，是实力的较量，更需要好好表现自己！ 如下程序段，问计算机如何压栈，压了什么，压的顺序如何？ void b( ) { ..... a(c,d,e,f); ..... } 首先一个问题，栈是用来干什么的?堆又是用来干什么的？栈和堆在内存中一般是相向增长，栈用来保存过程调用中产生的活跃记录(activation record）。活跃记录用来记录机器状态的信息，比如PC(程序计数器)的值、寄存器的值、活跃域为整个被调用函数的数据对象。这样，当从被调用者中返回时，就能直接使用活跃记录恢复调用点，并接着执行调用点后的代码。所以活跃记录还需要包含一些返回信息。 一个活跃记录总体包含： 实际参数：被调用函数使用的参数 返回值： 保存函数的返回值 控制链接：指向调用者的活跃记录 访问链接：被调用者可能需要的其他值，比如在其他活跃记录中保存的变量。 机器状态：调用函数之前的系统状态，包括返回地址(PC的值)、寄存器的值 本地变量: 被调用函数需要记录的变量 临时变量：比如一些无法用寄存器保存的表达式的值(?) 栈调用过程：当一个函数被调用时，如上的活跃记录将会被压入栈中，被调用函数在执行过程中，使用栈顶的内存，之后弹出活跃记录，栈顶为调用函数的活跃记录，恢复调用函数的现场，继续执行。 调用者和被调用者需要分别在被调用者的活跃记录中做操作，才能保证整个函数调用过程可行，要让被调用者做尽可能多的工作，以减少实际程序代码量。实际中需要考虑活跃记录中各项的压栈顺序问题： 调用者和被调用者数据交换部分要放在活跃记录的开始，如函数参数。这样调用者就能立即将相关参数压栈而不用计算被调用者活跃记录的大小、不需要先创建整个活跃记录，也不需要知道活跃记录的排布。这种机制也能很好的支持可变参数的函数。 固定长度的项放在活跃记录的中部。包括控制链接，访问链接。如果每个调用过程都保存同样的此类状态信息，那我们就能使用相同的代码保存和恢复。而且，如果把机器状态信息标准化，GDB也能更方便的得到栈信息。 较晚才能确定大小的项放在活跃记录的末尾。虽然某些本地变量能静态确定大小，但还有一些，如Fortran中的动态数组在运行时才能确定大小。 面试题问，一个函数调用中各个参数的压栈顺序，即上面程序中a函数各个参数的压栈顺序.答案是从右往左压栈， 请看程序： #include; int add_tmp( int a) { return ++a; } int main() { int m,n; scanf("%d", &#38;m); n = add_tmp(m); printf(" %c,%d,%f \n",m+n,m,m); return 0; } 对应printf语句的汇编代码(x86平台)，可见压栈顺序是从右往左的。 <a href='http://www.lingcc.com/2010/09/27/11251/'>[...]</a><table class="wumii-related-items" cellspacing="0" cellpadding="2" border="0" width="100%" style="clear: both;">
    
    <tr>
        <td ><b><font size="-1"  style="display: block !important; padding: 20px 0 5px !important;">您可能也喜欢：</font></b></td>
    </tr>
    
            <tr>
                <td style="margin: 0 !important; padding: 0 !important; line-height: 20px !important;">
                    <img border="0" src="http://static.wumii.com/images/widget/widget_solidPoint.gif">
                    <a target="_blank" style="text-decoration: none !important;" href="http://app.wumii.com/ext/redirect.htm?url=http%3A%2F%2Fwww.lingcc.com%2F2010%2F09%2F28%2F11264%2F&from=http%3A%2F%2Fwww.lingcc.com%2F2010%2F09%2F27%2F11251%2F">
                        <font size="-1" color="#333333" style="line-height: 1.65em; font-size: 12px !important;">变参函数的压栈问题</font>
                    </a>
                </td>
            </tr>
            <tr>
                <td style="margin: 0 !important; padding: 0 !important; line-height: 20px !important;">
                    <img border="0" src="http://static.wumii.com/images/widget/widget_solidPoint.gif">
                    <a target="_blank" style="text-decoration: none !important;" href="http://app.wumii.com/ext/redirect.htm?url=http%3A%2F%2Fwww.lingcc.com%2F2010%2F10%2F13%2F11330%2F&from=http%3A%2F%2Fwww.lingcc.com%2F2010%2F09%2F27%2F11251%2F">
                        <font size="-1" color="#333333" style="line-height: 1.65em; font-size: 12px !important;">系统调用和库函数的区别</font>
                    </a>
                </td>
            </tr>
            <tr>
                <td style="margin: 0 !important; padding: 0 !important; line-height: 20px !important;">
                    <img border="0" src="http://static.wumii.com/images/widget/widget_solidPoint.gif">
                    <a target="_blank" style="text-decoration: none !important;" href="http://app.wumii.com/ext/redirect.htm?url=http%3A%2F%2Fwww.lingcc.com%2F2009%2F11%2F17%2F9999%2F&from=http%3A%2F%2Fwww.lingcc.com%2F2010%2F09%2F27%2F11251%2F">
                        <font size="-1" color="#333333" style="line-height: 1.65em; font-size: 12px !important;">今日记录-091117</font>
                    </a>
                </td>
            </tr>
            <tr>
                <td style="margin: 0 !important; padding: 0 !important; line-height: 20px !important;">
                    <img border="0" src="http://static.wumii.com/images/widget/widget_solidPoint.gif">
                    <a target="_blank" style="text-decoration: none !important;" href="http://app.wumii.com/ext/redirect.htm?url=http%3A%2F%2Fwww.lingcc.com%2F2009%2F11%2F20%2F10065%2F&from=http%3A%2F%2Fwww.lingcc.com%2F2010%2F09%2F27%2F11251%2F">
                        <font size="-1" color="#333333" style="line-height: 1.65em; font-size: 12px !important;">Gcc和Open64中的-fPIC选项</font>
                    </a>
                </td>
            </tr>
            <tr>
                <td style="margin: 0 !important; padding: 0 !important; line-height: 20px !important;">
                    <img border="0" src="http://static.wumii.com/images/widget/widget_solidPoint.gif">
                    <a target="_blank" style="text-decoration: none !important;" href="http://app.wumii.com/ext/redirect.htm?url=http%3A%2F%2Fwww.lingcc.com%2F2010%2F06%2F12%2F10969%2F&from=http%3A%2F%2Fwww.lingcc.com%2F2010%2F09%2F27%2F11251%2F">
                        <font size="-1" color="#333333" style="line-height: 1.65em; font-size: 12px !important;">关于并行貌似正确的废话–串行已经尽力了</font>
                    </a>
                </td>
            </tr>
    
    <tr>
        <td  align="right">
            <a style="text-decoration: none !important;" href="http://www.wumii.com/widget/relatedItems.htm" target="_blank" title="无觅相关文章插件">
                <font size="-1" color="#bbbbbb" style="display: block !important; font-family: arial !important; padding: 5px 0 !important; font-size: 12px !important; color: #bbb !important;">无觅</font>
            </a>
        </td>
    </tr>
</table>
<h3>相关文章：</h3><ul>
<li><a href='http://www.lingcc.com/2010/09/28/11264/' rel='bookmark' title='变参函数的压栈问题'>变参函数的压栈问题</a></li>
<li><a href='http://www.lingcc.com/2011/12/23/11907/' rel='bookmark' title='使用ld的wrap选项替换已有库函数'>使用ld的wrap选项替换已有库函数</a></li>
<li><a href='http://www.lingcc.com/2011/12/15/11902/' rel='bookmark' title='Python的import初探'>Python的import初探</a></li>
<li><a href='http://www.lingcc.com/2009/12/01/10171/' rel='bookmark' title='如何得到当前linux系统的页大小'>如何得到当前linux系统的页大小</a></li>
<li><a href='http://www.lingcc.com/2010/10/12/11305/' rel='bookmark' title='如何让程序屏蔽CTRL+C和CTRL+Z'>如何让程序屏蔽CTRL+C和CTRL+Z</a></li>
<li><a href='http://www.lingcc.com/2010/10/21/11371/' rel='bookmark' title='好消息：GodSon-T第一款芯片已经流片归来，正在测试'>好消息：GodSon-T第一款芯片已经流片归来，正在测试</a></li>
</ul>]]></description>
			<content:encoded><![CDATA[<p>今天面试某公司，很想拿到offer的一家，结果因为一道自己应该会，却没能很好答上来的面试题被刷，很可惜。不过，当时的表现也太过浮躁，自己太急于求成了，痛定思痛，是时候好好反思一下这道题，再深入学习一下这背后的知识。面试，是实力的较量，更需要好好表现自己！</p>
<p>如下程序段，问计算机如何压栈，压了什么，压的顺序如何？<span id="more-11251"></span></p>
<pre lang="c">void b( ) {
.....
a(c,d,e,f);
.....
}</pre>
<p>首先一个问题，栈是用来干什么的?堆又是用来干什么的？栈和堆在内存中一般是相向增长，栈用来保存过程调用中产生的活跃记录(activation record）。活跃记录用来记录机器状态的信息，比如PC(程序计数器)的值、寄存器的值、活跃域为整个被调用函数的数据对象。这样，当从被调用者中返回时，就能直接使用活跃记录恢复调用点，并接着执行调用点后的代码。所以活跃记录还需要包含一些返回信息。<br />
一个活跃记录总体包含：</p>
<ul>
<li class="level1">
<div class="li">实际参数：被调用函数使用的参数</div>
</li>
<li class="level1">
<div class="li">返回值： 保存函数的返回值</div>
</li>
<li class="level1">
<div class="li">控制链接：指向调用者的活跃记录</div>
</li>
<li class="level1">
<div class="li">访问链接：被调用者可能需要的其他值，比如在其他活跃记录中保存的变量。</div>
</li>
<li class="level1">
<div class="li">机器状态：调用函数之前的系统状态，包括返回地址(PC的值)、寄存器的值</div>
</li>
<li class="level1">
<div class="li">本地变量: 被调用函数需要记录的变量</div>
</li>
<li class="level1">
<div class="li">临时变量：比如一些无法用寄存器保存的表达式的值(?)</div>
</li>
</ul>
<div id="attachment_11255" class="wp-caption alignleft" style="width: 196px"><a rel="attachment wp-att-11255" href="http://www.lingcc.com/2010/09/27/11251/leak2/"><img class="size-medium wp-image-11255" title="leak2" src="http://www.lingcc.com/wp-content/uploads/2010/09/leak2-186x300.png" alt="" width="186" height="300" /></a><p class="wp-caption-text">调用栈示意图</p></div>
<p>栈调用过程：当一个函数被调用时，如上的活跃记录将会被压入栈中，被调用函数在执行过程中，使用栈顶的内存，之后弹出活跃记录，栈顶为调用函数的活跃记录，恢复调用函数的现场，继续执行。</p>
<p>调用者和被调用者需要分别在被调用者的活跃记录中做操作，才能保证整个函数调用过程可行，要让被调用者做尽可能多的工作，以减少实际程序代码量。实际中需要考虑活跃记录中各项的压栈顺序问题：</p>
<ul>
<li class="level1">
<div class="li">调用者和被调用者数据交换部分要放在活跃记录的开始，如函数参数。这样调用者就能立即将相关参数压栈而不用计算被调用者活跃记录的大小、不需要先创建整个活跃记录，也不需要知道活跃记录的排布。这种机制也能很好的支持可变参数的函数。</div>
</li>
<li class="level1">
<div class="li">固定长度的项放在活跃记录的中部。包括控制链接，访问链接。如果每个调用过程都保存同样的此类状态信息，那我们就能使用相同的代码保存和恢复。而且，如果把机器状态信息标准化，GDB也能更方便的得到栈信息。</div>
</li>
<li class="level1">
<div class="li">较晚才能确定大小的项放在活跃记录的末尾。虽然某些本地变量能静态确定大小，但还有一些，如Fortran中的动态数组在运行时才能确定大小。</div>
</li>
</ul>
<p>面试题问，一个函数调用中各个参数的压栈顺序，即上面程序中a函数各个参数的压栈顺序.答案是从右往左压栈，<br />
请看程序：</p>
<pre lang="c">#include;
int add_tmp( int a) {
  return ++a;
}
int main() {
	int m,n;
	scanf("%d", &amp;m);
        n = add_tmp(m);
	printf(" %c,%d,%f \n",m+n,m,m);
	return 0;
}</pre>
<p>对应printf语句的汇编代码(x86平台)，可见压栈顺序是从右往左的。</p>
<pre class="code">	call	add_tmp
	movl	%eax, 28(%esp)
	movl	24(%esp), %ebx
	movl	24(%esp), %ecx
	movl	24(%esp), %eax
	movl	%eax, %edx
	addl	28(%esp), %edx
	movl	$.LC1, %eax
	movl	%ebx, 12(%esp)
	movl	%ecx, 8(%esp)
	movl	%edx, 4(%esp)
	movl	%eax, (%esp)
	call	printf</pre>
<p>为何要从右往左？有什么特殊考虑？答案是：没有那么多为什么，就像小尾端和大尾端一样，只是个实现问题，特殊的考虑，没有搜到，<a class="urlextern" title="http://bytes.com/topic/c/answers/626516-parameter-passing-via-stack" rel="nofollow" href="http://bytes.com/topic/c/answers/626516-parameter-passing-via-stack">这个网页</a>谈到一些，<a class="urlextern" title="http://en.wikibooks.org/wiki/Embedded_Systems/Mixed_C_and_Assembly_Programming" rel="nofollow" href="http://en.wikibooks.org/wiki/Embedded_Systems/Mixed_C_and_Assembly_Programming">Embedded Systems/Mixed C and Assembly Programming</a>中明确说明这只是个具体实现问题。。。(本博看到这个答案后，情绪有稍许波动)</p>
<p><a rel="attachment wp-att-11256" href="http://www.lingcc.com/2010/09/27/11251/beiju/"><img class="alignleft size-medium wp-image-11256" title="beiju" src="http://www.lingcc.com/wp-content/uploads/2010/09/beiju-300x221.jpg" alt="" width="300" height="221" /></a></p>
<p>参考：</p>
<ul>
<li>龙书 第二版影印版  p427-p437</li>
</ul>
<div style=float:left><!-- JiaThis Button BEGIN -->
<div id="jiathis_style_32x32">
	<a class="jiathis_button_qzone"></a>
	<a class="jiathis_button_tsina"></a>
	<a class="jiathis_button_tqq"></a>
	<a class="jiathis_button_renren"></a>
	<a class="jiathis_button_kaixin001"></a>
	<a href="http://www.jiathis.com/share/" class="jiathis jiathis_txt jtico jtico_jiathis" target="_blank"></a>
	<a class="jiathis_counter_style"></a>
</div>
<script type="text/javascript" src="http://v2.jiathis.com/code/jia.js" charset="utf-8"></script>
<!-- JiaThis Button END --></div><p><h3>相关文章：</h3><ul>
<li><a href='http://www.lingcc.com/2010/09/28/11264/' rel='bookmark' title='变参函数的压栈问题'>变参函数的压栈问题</a></li>
<li><a href='http://www.lingcc.com/2011/12/23/11907/' rel='bookmark' title='使用ld的wrap选项替换已有库函数'>使用ld的wrap选项替换已有库函数</a></li>
<li><a href='http://www.lingcc.com/2011/12/15/11902/' rel='bookmark' title='Python的import初探'>Python的import初探</a></li>
<li><a href='http://www.lingcc.com/2009/12/01/10171/' rel='bookmark' title='如何得到当前linux系统的页大小'>如何得到当前linux系统的页大小</a></li>
<li><a href='http://www.lingcc.com/2010/10/12/11305/' rel='bookmark' title='如何让程序屏蔽CTRL+C和CTRL+Z'>如何让程序屏蔽CTRL+C和CTRL+Z</a></li>
<li><a href='http://www.lingcc.com/2010/10/21/11371/' rel='bookmark' title='好消息：GodSon-T第一款芯片已经流片归来，正在测试'>好消息：GodSon-T第一款芯片已经流片归来，正在测试</a></li>
</ul></p>]]></content:encoded>
			<wfw:commentRss>http://www.lingcc.com/2010/09/27/11251/feed/</wfw:commentRss>
		<slash:comments>27</slash:comments>
		</item>
		<item>
		<title>关于并行貌似正确的废话&#8211;串行已经尽力了</title>
		<link>http://www.lingcc.com/2010/06/12/10969/</link>
		<comments>http://www.lingcc.com/2010/06/12/10969/#comments</comments>
		<pubDate>Sat, 12 Jun 2010 11:28:46 +0000</pubDate>
		<dc:creator>erlv</dc:creator>
				<category><![CDATA[编译前沿]]></category>
		<category><![CDATA[编译技术]]></category>
		<category><![CDATA[多核]]></category>
		<category><![CDATA[并行]]></category>
		<category><![CDATA[并行计算]]></category>
		<category><![CDATA[空闲时优化]]></category>
		<category><![CDATA[编译器]]></category>
		<category><![CDATA[计算技术未来]]></category>
		<category><![CDATA[过程间优化]]></category>
		<category><![CDATA[运行时技术]]></category>

		<guid isPermaLink="false">http://www.lingcc.com/?p=10969</guid>
		<description><![CDATA[《关于并行貌似正确的废话》系列文章： 《关于并行貌似正确的废话–串行已经尽力了》 《关于并行貌似正确的废话-程序语言发展的启示》 《关于并行貌似正确的废话-程序员是优秀的管理者》 在没有革命性的芯片制造技术之前，咱们必须得接受要想快，只能并行！即使出来了新的CPU制造技术，只要有计算，就需要时间，只要有时间需求，人就想要程序跑的越快越好。这是必须的，除了程序员，没有人会享受程序运行的过程。用计算机的人只想要结果！所以性能，将是永恒的主题。 怎么提升性能?咱们从下往上看。 单核CPU已经差不多了，流水线，多发射，延迟槽，超线程，单指令流多数据流(SIMD),能用的技术全都用上了。 频率也不能再升了，访存速度也已经差不多了，卖出去的CPU，一半都是在卖Cache，计算单元占的面积在慢慢变小。于是，我们不得不使用多核，众核。 编译器也很为难，从几十年前开始，吭哧吭哧到现在，能用的招全都用上了，先在汇编里找，不行就在源程序分析中找，有没有公共的子表达式可以删除，有没有常数可以传播。再不行，转SSA形式，找出每个变量在哪儿定义的，在哪儿使用的，有没有多余的定义和使用，有没有可以传播下去的公共子表达式和常数。还觉得不够？过程间并行，要编译的函数，要编译的文件，通通拿过来，搅到一起，在仔细分析！接着，部分冗余删除！在IF条件里面的定义先挪到外面，再对两个分支分别做处理。循环能向量化的向量化，能合并的合并，能展开的展开。能做软流水的软流水。弄了半天，发现寄存器不够用了，于是图着色分配寄存器。几十年就这样过去了，性能有所提升，但不高。一不小心还会出错。明明觉得是个优化，增加之后，发现性能却降了不少。颠倒颠倒做优化的顺序都会给性能和正确性造成很大影响。而且编译时间也会增加不少，搞开发的人不乐意了，哥要写程序，写的过程中，编译一次，你丫要我等十几分钟？！几十年了，静态编译优化做到现在也尽力了。 静态优化不行，用反馈。程序给我，编译器用我的，编出的程序给你运行，收集你使用程序的信息，我再用这些信息决定怎么做优化。优化做了，性能提升了，可是程序输入一变，傻了。性能比不做反馈优化又降了不少。怎么办？投机！我把你的程序拆，编译器拆，不知道怎么拆就使劲做依赖分析，能拆多少拆多少，拆出来的部分，能并行的就并行，增加个运行时支持，拆出来的部分先并行执行着，程序需要的时候，就直接把结果奉上。但是问题又来了，有投机就有失败，有失败就有代价。更何况盲目的投机还会造成cache 污染，存储一致性问题。投机失败的恢复问题。每次投机带来的能耗问题。。。。。 串行皱起眉头，一脸苦涩：大哥，我尽力了，已经不行了！ 相关文章： 关于并行貌似正确的废话-程序员是优秀的管理者 关于并行貌似正确的废话-程序语言发展的启示 期待未来-一张趣图 探秘CPU性能测试：Spec CPU2000之整点篇 前瞻-全时优化和LLVM-1 《多核编译技术研讨会》记二
<h3>相关文章：</h3><ul>
<li><a href='http://www.lingcc.com/2010/06/14/10972/' rel='bookmark' title='关于并行貌似正确的废话-程序员是优秀的管理者'>关于并行貌似正确的废话-程序员是优秀的管理者</a></li>
<li><a href='http://www.lingcc.com/2010/06/13/10970/' rel='bookmark' title='关于并行貌似正确的废话-程序语言发展的启示'>关于并行貌似正确的废话-程序语言发展的启示</a></li>
<li><a href='http://www.lingcc.com/2010/05/07/10916/' rel='bookmark' title='期待未来-一张趣图'>期待未来-一张趣图</a></li>
<li><a href='http://www.lingcc.com/2010/04/14/10736/' rel='bookmark' title='探秘CPU性能测试：Spec CPU2000之整点篇'>探秘CPU性能测试：Spec CPU2000之整点篇</a></li>
<li><a href='http://www.lingcc.com/2010/04/07/10721/' rel='bookmark' title='前瞻-全时优化和LLVM-1'>前瞻-全时优化和LLVM-1</a></li>
<li><a href='http://www.lingcc.com/2009/12/05/10234/' rel='bookmark' title='《多核编译技术研讨会》记二'>《多核编译技术研讨会》记二</a></li>
</ul>]]></description>
			<content:encoded><![CDATA[<p>《关于并行貌似正确的废话》系列文章：</p>
<ol>
<li>《<a title="编辑 “关于并行貌似正确的废话–串行已经尽力了”" href="http://www.lingcc.com/2010/06/12/10969/" target="_blank">关于并行貌似正确的废话–串行已经尽力了</a>》</li>
<li><span style="text-decoration: underline;">《</span><a href=" http://www.lingcc.com/2010/06/13/10970/" target="_blank">关于并行貌似正确的废话-程序语言发展的启示</a><span style="text-decoration: underline;">》</span></li>
<li><a href="http://www.lingcc.com/2010/06/14/10972/" target="_blank">《关于并行貌似正确的废话-程序员是优秀的管理者》</a></li>
</ol>
<p>在没有革命性的芯片制造技术之前，咱们必须得接受要想快，只能并行！即使出来了新的CPU制造技术，只要有计算，就需要时间，只要有时间需求，人就想要程序跑的越快越好。这是必须的，除了程序员，没有人会享受程序运行的过程。用计算机的人只想要结果！所以性能，将是永恒的主题。</p>
<p>怎么提升性能?咱们从下往上看。</p>
<p><span id="more-10969"></span>单核CPU已经差不多了，流水线，多发射，延迟槽，超线程，单指令流多数据流(SIMD),能用的技术全都用上了。 频率也不能再升了，访存速度也已经差不多了，卖出去的CPU，一半都是在卖Cache，计算单元占的面积在慢慢变小。于是，我们不得不使用多核，众核。</p>
<p>编译器也很为难，从几十年前开始，吭哧吭哧到现在，能用的招全都用上了，先在汇编里找，不行就在源程序分析中找，有没有公共的子表达式可以删除，有没有常数可以传播。再不行，转SSA形式，找出每个变量在哪儿定义的，在哪儿使用的，有没有多余的定义和使用，有没有可以传播下去的公共子表达式和常数。还觉得不够？过程间并行，要编译的函数，要编译的文件，通通拿过来，搅到一起，在仔细分析！接着，部分冗余删除！在IF条件里面的定义先挪到外面，再对两个分支分别做处理。循环能向量化的向量化，能合并的合并，能展开的展开。能做软流水的软流水。弄了半天，发现寄存器不够用了，于是图着色分配寄存器。几十年就这样过去了，性能有所提升，但不高。一不小心还会出错。明明觉得是个优化，增加之后，发现性能却降了不少。颠倒颠倒做优化的顺序都会给性能和正确性造成很大影响。而且编译时间也会增加不少，搞开发的人不乐意了，哥要写程序，写的过程中，编译一次，你丫要我等十几分钟？！几十年了，静态编译优化做到现在也尽力了。</p>
<p>静态优化不行，用反馈。程序给我，编译器用我的，编出的程序给你运行，收集你使用程序的信息，我再用这些信息决定怎么做优化。优化做了，性能提升了，可是程序输入一变，傻了。性能比不做反馈优化又降了不少。怎么办？投机！我把你的程序拆，编译器拆，不知道怎么拆就使劲做依赖分析，能拆多少拆多少，拆出来的部分，能并行的就并行，增加个运行时支持，拆出来的部分先并行执行着，程序需要的时候，就直接把结果奉上。但是问题又来了，有投机就有失败，有失败就有代价。更何况盲目的投机还会造成cache 污染，存储一致性问题。投机失败的恢复问题。每次投机带来的能耗问题。。。。。</p>
<p>串行皱起眉头，一脸苦涩：大哥，我尽力了，已经不行了！</p>
<p><a href="http://www.lingcc.com/wp-content/uploads/2010/06/jiushan.jpg"><img class="alignnone size-medium wp-image-10974" title="jiushan" src="http://www.lingcc.com/wp-content/uploads/2010/06/jiushan-245x300.jpg" alt="" width="245" height="300" /></a></p>
<div style=float:left><!-- JiaThis Button BEGIN -->
<div id="jiathis_style_32x32">
	<a class="jiathis_button_qzone"></a>
	<a class="jiathis_button_tsina"></a>
	<a class="jiathis_button_tqq"></a>
	<a class="jiathis_button_renren"></a>
	<a class="jiathis_button_kaixin001"></a>
	<a href="http://www.jiathis.com/share/" class="jiathis jiathis_txt jtico jtico_jiathis" target="_blank"></a>
	<a class="jiathis_counter_style"></a>
</div>
<script type="text/javascript" src="http://v2.jiathis.com/code/jia.js" charset="utf-8"></script>
<!-- JiaThis Button END --></div><p><h3>相关文章：</h3><ul>
<li><a href='http://www.lingcc.com/2010/06/14/10972/' rel='bookmark' title='关于并行貌似正确的废话-程序员是优秀的管理者'>关于并行貌似正确的废话-程序员是优秀的管理者</a></li>
<li><a href='http://www.lingcc.com/2010/06/13/10970/' rel='bookmark' title='关于并行貌似正确的废话-程序语言发展的启示'>关于并行貌似正确的废话-程序语言发展的启示</a></li>
<li><a href='http://www.lingcc.com/2010/05/07/10916/' rel='bookmark' title='期待未来-一张趣图'>期待未来-一张趣图</a></li>
<li><a href='http://www.lingcc.com/2010/04/14/10736/' rel='bookmark' title='探秘CPU性能测试：Spec CPU2000之整点篇'>探秘CPU性能测试：Spec CPU2000之整点篇</a></li>
<li><a href='http://www.lingcc.com/2010/04/07/10721/' rel='bookmark' title='前瞻-全时优化和LLVM-1'>前瞻-全时优化和LLVM-1</a></li>
<li><a href='http://www.lingcc.com/2009/12/05/10234/' rel='bookmark' title='《多核编译技术研讨会》记二'>《多核编译技术研讨会》记二</a></li>
</ul></p>]]></content:encoded>
			<wfw:commentRss>http://www.lingcc.com/2010/06/12/10969/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
		<item>
		<title>认识静态链接库</title>
		<link>http://www.lingcc.com/2010/05/25/10951/</link>
		<comments>http://www.lingcc.com/2010/05/25/10951/#comments</comments>
		<pubDate>Tue, 25 May 2010 13:33:01 +0000</pubDate>
		<dc:creator>erlv</dc:creator>
				<category><![CDATA[系统软件及库]]></category>
		<category><![CDATA[编译技术]]></category>
		<category><![CDATA[compiler infrastructure]]></category>
		<category><![CDATA[gcc]]></category>
		<category><![CDATA[glibc]]></category>
		<category><![CDATA[ld]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[windows]]></category>
		<category><![CDATA[工具链]]></category>
		<category><![CDATA[操作系统 Operating system]]></category>
		<category><![CDATA[系统健壮性]]></category>
		<category><![CDATA[编译器]]></category>
		<category><![CDATA[编译器开发]]></category>
		<category><![CDATA[运行时技术]]></category>
		<category><![CDATA[链接]]></category>

		<guid isPermaLink="false">http://www.lingcc.com/?p=10951</guid>
		<description><![CDATA[介绍静态链接库是什么，为何要有静态链接库，动态链接库和共享库，如何使用，创建，编辑静态练级库。
<h3>相关文章：</h3><ul>
<li><a href='http://www.lingcc.com/2010/05/07/10916/' rel='bookmark' title='期待未来-一张趣图'>期待未来-一张趣图</a></li>
<li><a href='http://www.lingcc.com/2010/04/30/10822/' rel='bookmark' title='前瞻-LLVM大事记(2004-2010)'>前瞻-LLVM大事记(2004-2010)</a></li>
<li><a href='http://www.lingcc.com/2009/12/29/10503/' rel='bookmark' title='GCC初窥'>GCC初窥</a></li>
<li><a href='http://www.lingcc.com/2009/12/31/10534/' rel='bookmark' title='Gentoo中的交叉编译利器&#8211;crossdev'>Gentoo中的交叉编译利器&#8211;crossdev</a></li>
<li><a href='http://www.lingcc.com/2010/07/16/11081/' rel='bookmark' title='多面体模型是编译器循环优化的未来吗？'>多面体模型是编译器循环优化的未来吗？</a></li>
<li><a href='http://www.lingcc.com/2008/08/27/9982/' rel='bookmark' title='zz Linux下的段错误的原因及调试'>zz Linux下的段错误的原因及调试</a></li>
</ul>]]></description>
			<content:encoded><![CDATA[<h4>什么是静态链接库？</h4>
<p>静态链接库，即static library或 statically-linked library。和动态链接库，即dynamic library 或dynamicly-linked library相对，是Windows和Linux系统中比较常用的库文件。Windows中分别用SLL和DLL文件表示，Linux中分别是.a和.so文件.</p>
<p>静态链接库实际是一些object files(.o文件)和头文件的压缩包，通过GNU工具链中的ar(archiver)程序创建。</p>
<h5>静态链接库、动态链接库和共享库</h5>
<p>那为何还要有动态链接库呢？静态练级库虽然能很好的节省编译时间。对于一个简单的ls程序，我们需要有屏幕输出，有字符串和格式操作，有文件系统访问等等函数，都要在一个程序中。此时，这个程序会很大。一个小小的ls可能都会有好几兆。如果还有个rm程序，同样也需要屏幕输出，文件系统访问。那么这两个东西，我们可以放到两个库文件里，在执行ls，或者rm的时候，用到屏幕输出操作，就将相应的函数对应的机器码载入内存中，执行。然后再从内存中释放。接着载入文件系统访问的相关函数。这样我们的程序就能变小很多。这种可以动态装载到内存中的库文件就是动态链接库了。Windows下的DLL文件就是动态链接库。</p>
<p><span id="more-10951"></span></p>
<p>还有个问题，其实ls和rm使用的屏幕输出函数是一样的。内存很小的时候，同时执行ls和rm，有必要同时载入两份相同的代码到内存中吗？于是就有了共享库，不同的程序可以共享相同的代码。都可以访问，执行。于是就有了共享库的概念。Linux下的.so文件就是共享库。</p>
<p>这时候又有个问题，程序执行时，访存，跳转的地址是一定的，那两个程序又如何共享相同的库代码呢？这就靠位置无关的代码生成了。本博曾经写过文章介绍它们，请参考<a href="http://www.lingcc.com/2009/11/20/10065/" target="_blank">Gcc和Open64中的-fPIC选项</a> 和<a href="http://www.lingcc.com/2010/01/08/10609/" target="_blank">GCC中的pie和fpie选项</a>两篇文章。</p>
<p>下图是关于共享库和静态链接库的示意图，可以简单看出些区别。</p>
<div id="attachment_10952" class="wp-caption alignnone" style="width: 351px"><a href="http://www.lingcc.com/wp-content/uploads/2010/05/figure2.gif"><img class="size-full wp-image-10952" title="静态链接库和共享库" src="http://www.lingcc.com/wp-content/uploads/2010/05/figure2.gif" alt="" width="341" height="265" /></a><p class="wp-caption-text">静态链接库和共享库</p></div>
<h4>为什么要有静态链接库？</h4>
<p>首先，随着程序规模的增加，有些常用函数可能不需要每次都编译，于是就可以把它们作为库的方式来存放。这样用户就能很方便的链接生成最后的程序，不用一遍遍的重新编译某些常用程序文件。必须内核，硬件驱动，文件系统，glibc等等库文件，一些基本函数都采用了这种形式。</p>
<p>其次，一些闭源代码，可以通过库的方式来发布，这样可以保证代码不公开。</p>
<p>再次，相比动态链接的程序，或者共享库程序，连接到静态库的程序会快1%-5%左右。</p>
<p>另外，有些特殊环境，必须使用静态链接库。比如在Linux系统，需要chroot到另一个系统环境中时，动态链接库就不再起作用，因为那些是在原来系统的文件树下，如/usr/lib.但在chroot的环境中，无法访问。</p>
<h4>怎么用静态链接库？</h4>
<p>既然静态链接库的出现，是为了缩短编译时间。而普通可执行程序又可以分为静态链和动态链两种形式。因此我们就分开介绍之，原因无他，只是想顺便介绍一下动态链可执行程序和静态链可执行程序在运行时的一些区别。</p>
<p>对于静态链接库的应用，加上-lname，就会链接libname.a这个静态链接库文件。一般静态链接库文件的搜索路径为系统默认的路径，如/usr/lib/和当前路径。你也可以用过-L选项，指定GCC搜索某个特定文件夹。注意-l和-L的参数要加载待编译源码文件之后。</p>
<p>静态链接库既可以在编译时用于生成单个可执行文件，也可以在运行时根据编译或者连接时确定的静态偏移量载入内存中。</p>
<h5>编译静态链接可执行程序</h5>
<p>编译静态链可执行程序,对于gcc，只要加上-static即可。</p>
<p>编译时，程序中若有对库函数的调用，编译器或者连接器就会将库中相应的代码拷贝到目标文件中，生成一个独立的可执行文件。</p>
<h5>编译动态链接可执行程序</h5>
<p>不加-static编译生成的可执行程序都是动态链接的，编译时所做工作很少，仅仅记录了该程序需要什么库函数，以及该库函数在库中到索引。</p>
<p>但对于动态链接程序，在系统启动该可执行程序时，装载器loader必须能找到相应的共享库文件.so文件或者静态链接库文件.a(已经很少使用这种形式了)，并将其载入内存中，一般的，有两种途径可以指定链接库文件的位置，</p>
<ul>
<li>编译动态链接可执行程序时，通过rpath指定，这个可以在编译时增加选项-Wl,-rpath=DIRS.这种方式不需要在运行时做任何修改，该选项会在连接时，写入可执行程序中。</li>
<li>运行时由ld.so指定。默认共享库搜索路径是/usr/local/lib，/usr/lib以及当前目录，你可以通过修改$LD_LIBRARY_PATH变量修改。系统管理员也可以在/etc/profile中修改，以便对所有用户有效。当然修改/etc/ld.so.conf也行，这样所有的程序都将更改寻找链接库文件的路径。</li>
</ul>
<div id="attachment_10953" class="wp-caption alignnone" style="width: 487px"><a href="http://www.lingcc.com/wp-content/uploads/2010/05/confused.jpg"><img class="size-full wp-image-10953" title="很晕吧" src="http://www.lingcc.com/wp-content/uploads/2010/05/confused.jpg" alt="" width="477" height="358" /></a><p class="wp-caption-text">很晕吧</p></div>
<h4>静态链接库的常用操作</h4>
<h5>制作静态链接库</h5>
<p><code>$ar rcs liba.a a.o b.o c.o a_header.h b_header.h</code></p>
<p>上面命令，将a.o, b.o, c.o, a_header.h, b_header.h作成静态链接库liba.a.</p>
<ul>
<li>选项r：将 .o , .h文件插入到liba.a文件中</li>
<li>c:创建一个压缩文件。</li>
<li>s：将.o文件的索引信息写入压缩文件中，或者升级已有索引。这和执行 ranlib liba.a的效果过一样。索引信息会存在压缩包的一个符号文件夹内，连接器可以通过名称找到位置，这样可以加速连接时间。</li>
</ul>
<h5>解压静态链接库</h5>
<p><code>$ar xv liba.a</code></p>
<p>该命令会把liba.a中所有的文件解压缩到当前目录下。</p>
<ul>
<li>x：解压缩该压缩包</li>
<li>v：可视化，解压缩同时输出到屏幕</li>
</ul>
<h5>查看内容</h5>
<p><code>$nm --print-armap liba.a</code></p>
<p>该命令查看liba.a中包含哪些文件，每个文件中包含哪些函数。</p>
<ul>
<li>在列出压缩包中所有文件中的符号，同时包含索引：每个元素到符号的映射</li>
</ul>
<h5>实践：</h5>
<p>本文不再给出具体实践，可以参考<a href="http://www.network-theory.co.uk/docs/gccintro/gccintro_25.html" target="_blank">An Introduction to GCC &#8211; Shared libraries and static libraries</a></p>
<h4>参考：</h4>
<ol>
<li><a href="http://www.network-theory.co.uk/docs/gccintro/gccintro_25.html">http://www.network-theory.co.uk/docs/gccintro/gccintro_25.html</a></li>
<li><a href="http://www.network-theory.co.uk/docs/gccintro/gccintro_25.html"></a><a href="http://en.wikipedia.org/wiki/Static_library">http://en.wikipedia.org/wiki/Static_library</a></li>
<li><a href="http://cpp.codenewbie.com/articles/cpp/1444/Static_Link_Librarys-Page_1.html">http://cpp.codenewbie.com/articles/cpp/1444/Static_Link_Librarys-Page_1.html</a></li>
<li><a href="http://tldp.org/HOWTO/Program-Library-HOWTO/static-libraries.html">http://tldp.org/HOWTO/Program-Library-HOWTO/static-libraries.html</a></li>
<li><a href="http://www.faqs.org/docs/linux_scratch/chapter05/whystatic.html">http://www.faqs.org/docs/linux_scratch/chapter05/whystatic.html</a></li>
<li><a href="http://en.wikipedia.org/wiki/Dynamic-link_library">http://en.wikipedia.org/wiki/Dynamic-link_library</a></li>
<li><a href="http://www.ibm.com/developerworks/linux/library/l-dynamic-libraries/index.html" target="_blank">http://www.ibm.com/developerworks/linux/library/l-dynamic-libraries/index.html</a></li>
</ol>
<div style=float:left><!-- JiaThis Button BEGIN -->
<div id="jiathis_style_32x32">
	<a class="jiathis_button_qzone"></a>
	<a class="jiathis_button_tsina"></a>
	<a class="jiathis_button_tqq"></a>
	<a class="jiathis_button_renren"></a>
	<a class="jiathis_button_kaixin001"></a>
	<a href="http://www.jiathis.com/share/" class="jiathis jiathis_txt jtico jtico_jiathis" target="_blank"></a>
	<a class="jiathis_counter_style"></a>
</div>
<script type="text/javascript" src="http://v2.jiathis.com/code/jia.js" charset="utf-8"></script>
<!-- JiaThis Button END --></div><p><h3>相关文章：</h3><ul>
<li><a href='http://www.lingcc.com/2010/05/07/10916/' rel='bookmark' title='期待未来-一张趣图'>期待未来-一张趣图</a></li>
<li><a href='http://www.lingcc.com/2010/04/30/10822/' rel='bookmark' title='前瞻-LLVM大事记(2004-2010)'>前瞻-LLVM大事记(2004-2010)</a></li>
<li><a href='http://www.lingcc.com/2009/12/29/10503/' rel='bookmark' title='GCC初窥'>GCC初窥</a></li>
<li><a href='http://www.lingcc.com/2009/12/31/10534/' rel='bookmark' title='Gentoo中的交叉编译利器&#8211;crossdev'>Gentoo中的交叉编译利器&#8211;crossdev</a></li>
<li><a href='http://www.lingcc.com/2010/07/16/11081/' rel='bookmark' title='多面体模型是编译器循环优化的未来吗？'>多面体模型是编译器循环优化的未来吗？</a></li>
<li><a href='http://www.lingcc.com/2008/08/27/9982/' rel='bookmark' title='zz Linux下的段错误的原因及调试'>zz Linux下的段错误的原因及调试</a></li>
</ul></p>]]></content:encoded>
			<wfw:commentRss>http://www.lingcc.com/2010/05/25/10951/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>前瞻-全时优化和LLVM-1</title>
		<link>http://www.lingcc.com/2010/04/07/10721/</link>
		<comments>http://www.lingcc.com/2010/04/07/10721/#comments</comments>
		<pubDate>Wed, 07 Apr 2010 14:30:56 +0000</pubDate>
		<dc:creator>erlv</dc:creator>
				<category><![CDATA[LLVM]]></category>
		<category><![CDATA[编译前沿]]></category>
		<category><![CDATA[编译技术]]></category>
		<category><![CDATA[编译理论实践和应用]]></category>
		<category><![CDATA[gcc]]></category>
		<category><![CDATA[JIT]]></category>
		<category><![CDATA[MPI]]></category>
		<category><![CDATA[N64]]></category>
		<category><![CDATA[Open64]]></category>
		<category><![CDATA[SSA]]></category>
		<category><![CDATA[中间表示]]></category>
		<category><![CDATA[全时优化]]></category>
		<category><![CDATA[工具链]]></category>
		<category><![CDATA[性能]]></category>
		<category><![CDATA[空闲时优化]]></category>
		<category><![CDATA[编程技术]]></category>
		<category><![CDATA[编译器]]></category>
		<category><![CDATA[编译器设计]]></category>
		<category><![CDATA[虚拟机]]></category>
		<category><![CDATA[过程间优化]]></category>
		<category><![CDATA[运行时技术]]></category>
		<category><![CDATA[链接]]></category>

		<guid isPermaLink="false">http://www.lingcc.com/?p=10721</guid>
		<description><![CDATA[读论文&#60;LLVM: A Compilation Framework for Lifelong Program Analysis &#38; Transformation&#62; CGO 04 1，写在前面的话 全时优化(LifeLong Optimization)对于每个编译爱好者来说，太有魅力了。我在起初也是被这个题目所吸引打算一探究竟。本文是04年LLVM的最早两位开发者Chris Lattner和Vikram Adve所写，发表在04年的CGO上， 先来说说LLVM的历史。2000年LLVM开始开发，2005年Apple雇了Chris Lattner，LLVM也相当于成了Apple的官方支持的编译器。Apple已经将它用在OpenCL的流水线优化，Xcode已经能使用llvm-gcc编译代码。可以说05年之前LLVM一直都是学术界的东西，05年之后用于工业界.而这篇文章写在04年.本博最近听过一个关于LLVM的讨论会，会中有资深人士提到LLVM现在越来越像一个普通的编译器。说这番话的意思是，我们可以从这篇文章里找到LLVM的架构设计和早期的一些实现思想，但请不要迷信LLVM现在有多么神奇，每个架构都会有它的优缺点。 这篇文章，我现在已经读完了理论和介绍部分，性能评测部分还没有读。所以标题里面加了个1，因为接下来，还想作几件事，一是读完文章，二是跟踪一下Chris Lattner最近几年的文章，三是尝试将Open64和LLVM做个对比，最后看看代码。所以敬请期待之后的系列文章。 2.总览 先来解释Lifetime:文中分为编译时，链接时，安装时，运行时，空闲时五个阶段。这五个阶段都存在着优化机会：编译时的普通静态优化；链接时的过程间优化；安装时的目标机相关优化；运行时的动态优化和空闲时的profile制导优化。LLVM最早的设计就是针对以上几种优化进行的。 既然需要运行时和空闲时优化，就必须有必要的运行时环境和profile插装方式。因此注定LLVM的中间表示将占据非常重要的位置。编译和链接是为了生成中间表示，运行和空闲时则需要对中间表示的解释和执行。因此LLVM用上了目前编译所开发的所有技术:静态编译优化，JIT，虚拟机，解释器，运行时技术等等。也注定了LLVM要有一整套的工具链和环境来完成上述工作。 作者给出了LLVM架构设计中由于支持全时优化的五个特性，并支持现阶段，并无任何一种系统能同时具备这五个特性，不管是编译器，虚拟机还是其他系统。这五个特性是： 保持程序信息不变 离线本地代码生成 基于用户的profile和优化 透明的运行时模型 统一的全程序编译。 作者从两个角度来论述LLVM对全时优化的支持，一是LLVM的中间表示设计；二是LLVM的整体架构设计。 3.中间表示 LLVM的中间表示采取类RISC指令集，但包含关键的高层类型信息，精确控制流图和数据流图。LLVM的中间表示的几个特性：低层，语言无关的类型系 统；提供保存类型信息又能做类型转换和底层地址运算的指令；两个底层例外处理指令。LLVM中间表示之所以能做到与源程序独立，是因为它使用了比汇编稍大 的底层指令级及存储模型但并不暴露任何实际运行时需求和源程序语义需求。这种中间表示也决定了LLVM的局限性，对于源源转换之类的优化，LLVM就无法 直接在中间表示发力。 作者主要从五个方面介绍了LLVM中间表示的特点：指令集、语言无关的类型信息、存储模型、例外处理截止和三种中间表示形式相互透明(普通文本，二进制和内存中) 指令集： LLVM的中间表示采用原始处理器中的关键操作，回避物理寄存器、流水线、底层调用转换等细节，但为虚拟寄存器提供了集中类型(布尔型、整型、浮点型、指针),这些虚拟寄存器都采用SSA的形式。LLVM中有31个指令，多数采用了类型重载，且多为三地址形式.LLVM的每个虚拟寄存器都使用SSA的形式，而存储位置则不是SSA，这是因为存储可能存在别名。虚拟寄存器采用SSA能带来精确的定义-使用关系。另外LLVM也简化了控制流图，每个函数都转化为基本块的集合。每个基本块都有LLVM指令序列组成，结束基本块都有一个退出指令，如return，unwind，invoke。 语言无关的类型信息： LLVM中每个SSA 虚拟寄存器和存储对象都有和其关联的类型，所有的操作也都有严格的类型规则。LLVM的类型系统包括了如下类型:void,bool, signed/unsigned int(8bit to 64bit),single float,double float和四种衍生类型：pointer,array,structure和function。作者认为很多高层的类型都能使用这些类型表示。如C++中的类继承就能使用structure,function和function pointer array 来表示；而且作者也认为以上这些类型基本胜任经典的语言无关的程序分析和优化。因为LLVM的中间表示层次低，就需要支持弱类型语言，因此为提高在LLVM程序中声明类型的可靠性，LLVM使用一些指针分析算法来来判断所访问的内存与指针的类型是否可以可靠的相互转换。LLVM的类型转换仅能通过cast指令从一种类型转换为另一种类型。LLVM的指针算术运算通过getelementptr来实现，该指令力保在做地址运算时指令安全。load和store指令则只负责取和存。 精确存储分配和统一存储模型： LLVM通过三个指令实现存储操作：malloc，free和alloca。malloc负责在堆上分配带类型的存储位置；free负责释放malloc分配的存储空间；alloca和malloc相似，它分配的是在当前栈帧內分配存储而非堆，该内存将在函数返回时自动收回。LLVM中所有地址对象都被精确分配地址。全局变量和函数定义都被分配一个对象地址。这使得一个 统一的存储模型被建立。 函数调用和例外处理： <a href='http://www.lingcc.com/2010/04/07/10721/'>[...]</a>
<h3>相关文章：</h3><ul>
<li><a href='http://www.lingcc.com/2010/04/29/10728/' rel='bookmark' title='前瞻-全时优化和LLVM-2'>前瞻-全时优化和LLVM-2</a></li>
<li><a href='http://www.lingcc.com/2010/04/30/10822/' rel='bookmark' title='前瞻-LLVM大事记(2004-2010)'>前瞻-LLVM大事记(2004-2010)</a></li>
<li><a href='http://www.lingcc.com/2009/12/29/10503/' rel='bookmark' title='GCC初窥'>GCC初窥</a></li>
<li><a href='http://www.lingcc.com/2009/11/18/10000/' rel='bookmark' title='Open64课程-简介，概述和中间表示'>Open64课程-简介，概述和中间表示</a></li>
<li><a href='http://www.lingcc.com/2009/11/19/10024/' rel='bookmark' title='Open64课程-编译过程'>Open64课程-编译过程</a></li>
<li><a href='http://www.lingcc.com/2009/12/14/10295/' rel='bookmark' title='open64课程&#8211;过程间分析优化(IPA)'>open64课程&#8211;过程间分析优化(IPA)</a></li>
</ul>]]></description>
			<content:encoded><![CDATA[<p>读论文&lt;<a href="http://llvm.org/pubs/2004-01-30-CGO-LLVM.html" target="_blank">LLVM: A Compilation Framework for Lifelong Program Analysis &amp; Transformation</a>&gt; CGO 04</p>
<h3>1，写在前面的话</h3>
<p>全时优化(LifeLong Optimization)对于每个编译爱好者来说，太有魅力了。我在起初也是被这个题目所吸引打算一探究竟。本文是04年LLVM的最早两位开发者Chris Lattner和Vikram Adve所写，发表在04年的CGO上，</p>
<p>先来说说LLVM的历史。2000年LLVM开始开发，2005年Apple雇了Chris Lattner，LLVM也相当于成了Apple的官方支持的编译器。Apple已经将它用在OpenCL的流水线优化，Xcode已经能使用llvm-gcc编译代码。可以说05年之前LLVM一直都是学术界的东西，05年之后用于工业界.而这篇文章写在04年.本博最近听过一个关于LLVM的讨论会，会中有资深人士提到LLVM现在越来越像一个普通的编译器。说这番话的意思是，我们可以从这篇文章里找到LLVM的架构设计和早期的一些实现思想，但请不要迷信LLVM现在有多么神奇，每个架构都会有它的优缺点。</p>
<p>这篇文章，我现在已经读完了理论和介绍部分，性能评测部分还没有读。所以标题里面加了个1，因为接下来，还想作几件事，一是读完文章，二是跟踪一下Chris Lattner最近几年的文章，三是尝试将Open64和LLVM做个对比，最后看看代码。所以敬请期待之后的系列文章。<br />
<span id="more-10721"></span></p>
<h3>2.总览</h3>
<p>先来解释Lifetime:文中分为编译时，链接时，安装时，运行时，空闲时五个阶段。这五个阶段都存在着优化机会：编译时的普通静态优化；链接时的过程间优化；安装时的目标机相关优化；运行时的动态优化和空闲时的profile制导优化。LLVM最早的设计就是针对以上几种优化进行的。</p>
<p>既然需要运行时和空闲时优化，就必须有必要的运行时环境和profile插装方式。因此注定LLVM的中间表示将占据非常重要的位置。编译和链接是为了生成中间表示，运行和空闲时则需要对中间表示的解释和执行。因此LLVM用上了目前编译所开发的所有技术:静态编译优化，JIT，虚拟机，解释器，运行时技术等等。也注定了LLVM要有一整套的工具链和环境来完成上述工作。</p>
<p>作者给出了LLVM架构设计中由于支持全时优化的五个特性，并支持现阶段，并无任何一种系统能同时具备这五个特性，不管是编译器，虚拟机还是其他系统。这五个特性是：</p>
<ol>
<li>保持程序信息不变</li>
<li>离线本地代码生成</li>
<li>基于用户的profile和优化</li>
<li>透明的运行时模型</li>
<li>统一的全程序编译。</li>
</ol>
<p>作者从两个角度来论述LLVM对全时优化的支持，一是LLVM的中间表示设计；二是LLVM的整体架构设计。</p>
<h3>3.中间表示</h3>
<p>LLVM的中间表示采取类RISC指令集，但包含关键的高层类型信息，精确控制流图和数据流图。LLVM的中间表示的几个特性：低层，语言无关的类型系 统；提供保存类型信息又能做类型转换和底层地址运算的指令；两个底层例外处理指令。LLVM中间表示之所以能做到与源程序独立，是因为它使用了比汇编稍大 的底层指令级及存储模型但并不暴露任何实际运行时需求和源程序语义需求。这种中间表示也决定了LLVM的局限性，对于源源转换之类的优化，LLVM就无法 直接在中间表示发力。</p>
<p>作者主要从五个方面介绍了LLVM中间表示的特点：指令集、语言无关的类型信息、存储模型、例外处理截止和三种中间表示形式相互透明(普通文本，二进制和内存中)</p>
<h4>指令集：</h4>
<p>LLVM的中间表示采用原始处理器中的关键操作，回避物理寄存器、流水线、底层调用转换等细节，但为虚拟寄存器提供了集中类型(布尔型、整型、浮点型、指针),这些虚拟寄存器都采用SSA的形式。LLVM中有31个指令，多数采用了类型重载，且多为三地址形式.LLVM的每个虚拟寄存器都使用SSA的形式，而存储位置则不是SSA，这是因为存储可能存在别名。虚拟寄存器采用SSA能带来精确的定义-使用关系。另外LLVM也简化了控制流图，每个函数都转化为基本块的集合。每个基本块都有LLVM指令序列组成，结束基本块都有一个退出指令，如return，unwind，invoke。</p>
<h4>语言无关的类型信息：</h4>
<p>LLVM中每个SSA 虚拟寄存器和存储对象都有和其关联的类型，所有的操作也都有严格的类型规则。LLVM的类型系统包括了如下类型:void,bool, signed/unsigned int(8bit to 64bit),single float,double float和四种衍生类型：pointer,array,structure和function。作者认为很多高层的类型都能使用这些类型表示。如C++中的类继承就能使用structure,function和function pointer array 来表示；而且作者也认为以上这些类型基本胜任经典的语言无关的程序分析和优化。因为LLVM的中间表示层次低，就需要支持弱类型语言，因此为提高在LLVM程序中声明类型的可靠性，LLVM使用一些指针分析算法来来判断所访问的内存与指针的类型是否可以可靠的相互转换。LLVM的类型转换仅能通过cast指令从一种类型转换为另一种类型。LLVM的指针算术运算通过getelementptr来实现，该指令力保在做地址运算时指令安全。load和store指令则只负责取和存。</p>
<h4>精确存储分配和统一存储模型：</h4>
<p>LLVM通过三个指令实现存储操作：malloc，free和alloca。malloc负责在堆上分配带类型的存储位置；free负责释放malloc分配的存储空间；alloca和malloc相似，它分配的是在当前栈帧內分配存储而非堆，该内存将在函数返回时自动收回。LLVM中所有地址对象都被精确分配地址。全局变量和函数定义都被分配一个对象地址。这使得一个 统一的存储模型被建立。</p>
<h4>函数调用和例外处理：</h4>
<p>对于普通的函数调用，LLVM提供了一个带类型的call指令。LLVM有个与众不同的特性使得低级中间表示能处理高级程序例外，这种特性基于invoke和unwind两个指令实现。这两个指令共同支持了基于栈弹出的抽象例外处理模型。详细的机制论述请参考论文，作者用了将近一页的篇幅来论述。</p>
<h4>普通文本、二进制和内存中的表示形式：</h4>
<p>LLVM的中间表示是首个能同时等价的在二进制，普通文本和内存中(如编译器内部)表示的。指令集最初的设计就考虑到要能高效的即可作为一个中间表示，又能作为离线代码表示和编译器内部表示，并且在三者之间转换时无需任何语义变化。这三者之间的等价转换使得LLVM调试很方便。</p>
<p><em><span style="color: #000000;"><strong>正所谓，中间表示很重要，编译架构也得牛，眼高手低要不得，关键还得看评测。敬请关注下文 LLVM的架构介绍及整体评测。</strong></span></em></p>
<div style=float:left><!-- JiaThis Button BEGIN -->
<div id="jiathis_style_32x32">
	<a class="jiathis_button_qzone"></a>
	<a class="jiathis_button_tsina"></a>
	<a class="jiathis_button_tqq"></a>
	<a class="jiathis_button_renren"></a>
	<a class="jiathis_button_kaixin001"></a>
	<a href="http://www.jiathis.com/share/" class="jiathis jiathis_txt jtico jtico_jiathis" target="_blank"></a>
	<a class="jiathis_counter_style"></a>
</div>
<script type="text/javascript" src="http://v2.jiathis.com/code/jia.js" charset="utf-8"></script>
<!-- JiaThis Button END --></div><p><h3>相关文章：</h3><ul>
<li><a href='http://www.lingcc.com/2010/04/29/10728/' rel='bookmark' title='前瞻-全时优化和LLVM-2'>前瞻-全时优化和LLVM-2</a></li>
<li><a href='http://www.lingcc.com/2010/04/30/10822/' rel='bookmark' title='前瞻-LLVM大事记(2004-2010)'>前瞻-LLVM大事记(2004-2010)</a></li>
<li><a href='http://www.lingcc.com/2009/12/29/10503/' rel='bookmark' title='GCC初窥'>GCC初窥</a></li>
<li><a href='http://www.lingcc.com/2009/11/18/10000/' rel='bookmark' title='Open64课程-简介，概述和中间表示'>Open64课程-简介，概述和中间表示</a></li>
<li><a href='http://www.lingcc.com/2009/11/19/10024/' rel='bookmark' title='Open64课程-编译过程'>Open64课程-编译过程</a></li>
<li><a href='http://www.lingcc.com/2009/12/14/10295/' rel='bookmark' title='open64课程&#8211;过程间分析优化(IPA)'>open64课程&#8211;过程间分析优化(IPA)</a></li>
</ul></p>]]></content:encoded>
			<wfw:commentRss>http://www.lingcc.com/2010/04/07/10721/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>WebKit和Firefox的JavaScript性能对比</title>
		<link>http://www.lingcc.com/2010/01/22/10668/</link>
		<comments>http://www.lingcc.com/2010/01/22/10668/#comments</comments>
		<pubDate>Fri, 22 Jan 2010 14:37:22 +0000</pubDate>
		<dc:creator>erlv</dc:creator>
				<category><![CDATA[Linux系统]]></category>
		<category><![CDATA[编译技术]]></category>
		<category><![CDATA[console]]></category>
		<category><![CDATA[elf]]></category>
		<category><![CDATA[firefox]]></category>
		<category><![CDATA[gcc]]></category>
		<category><![CDATA[gentoo]]></category>
		<category><![CDATA[glibc]]></category>
		<category><![CDATA[intel]]></category>
		<category><![CDATA[JIT]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[MIPS]]></category>
		<category><![CDATA[nanojit]]></category>
		<category><![CDATA[spec]]></category>
		<category><![CDATA[TraceMonkey]]></category>
		<category><![CDATA[WebKit]]></category>
		<category><![CDATA[windows]]></category>
		<category><![CDATA[x86]]></category>
		<category><![CDATA[开源]]></category>
		<category><![CDATA[性能]]></category>
		<category><![CDATA[运行时技术]]></category>
		<category><![CDATA[链接]]></category>
		<category><![CDATA[龙芯]]></category>

		<guid isPermaLink="false">http://www.lingcc.com/?p=10668</guid>
		<description><![CDATA[严格的说WebKit仅仅是个浏览器核心，采用该核心的浏览器很多，如国内的搜狗浏览器，遨游浏览器。其他的如google的chrome(Windows平台，linux平台下为chromium),epiphany(linux平台下，gnome2.28版本之后),苹果的Safari 都采用了webkit的内核。Firefox则是采用Gecko的内核，这是NetScape公司开发的内核，后来开源，mozilla继续开发。另外，现在还有另外两种常见的浏览器内核，Trident主要用在IE系列上，Presto主要用在Opera上。 这篇文章仅仅针对浏览器处理JavaScript的性能作比较，主要在X86平台和龙芯平台。先来解释一下JavaScript，JavaScript是互联网内较为常用的脚本语言，面向对象，主要在浏览器内解释执行，用于生成动态网页，因为很多语言特性受Java影响，所以叫JavaScript。通过JavaScript，浏览器可以运行服务器想要在访问者终端上运行的一些计算程序，以达到更好的浏览体验。 再说说浏览器内核和JavaScript的关系，其实JavaScrip脚本的执行仅仅是浏览器内核的一部分，其他的还有Html语言的解释执行，网页的呈现等等也是内核要做的。之所以这么关心浏览器核心对JavaScript脚本的处理情况，是因为现在的很多应用不再是简单的网页浏览，如gmail，google reader，gooe wave还有一些网页3D特效等等都需要在客户机上作计算，这就需要JavaScript大显身手了。而且越来越多的应用依赖JavaScript，所以现在浏览器对JavaScript的处理速度直接影响着用户体验。目前WebKit的JavaScript引擎SquirrelFish，JavaScript的引擎是SpiderMonkey 目前JavaScript在大多数平台上的处理是靠解释执行的，又因为是动态类型，面向对象。。。，决定了JavaScript执行效率低，所以就诞生了各种针对JavaScript的优化，也有了测试JavaScipt解释器性能的BenchMark，目前常用的是Sunspider和google V8，这篇文章中的对比针对Sunspider测试集。 另外还要说说JIT，Just In time，转换，将部分程序代码直接转换成机器码执行，这种技术在运行时优化中比较常用，JavaScript是解释器，所以JIT在解释器中也是很重要的优化手段。目前X86的webkit和Firefox默认就有JIT支持，但龙芯平台上还没有，本博也是最早对龙芯2F平台有JIT支持的Webkit和firefox  JavaScript引擎作对比的，目前这两个JIT都还没有进入官方的代码库中，感兴趣的朋友可以在下面的前两个链接中找到相关源码。其中webkit的补丁还要做些宏的修改，改动不大。这两个都是从官方源码库checkout出来并修改之后的。其中firefox的JIT部分是由ZSC大牛写出来的，详细的讨论贴和测试结果可以在龙芯论坛看到，见下面的第三个链接。 x86下epiphany(webkit内核)和firefox开了jit之后的性能，如下 webkit Total: 833.6ms +/- 2.1% firefox Total: 1774.4ms +/- 2.7% （测试环境是我的笔记本 intel Pentium t2390,开了频率调节，所以波动较大)、两个差距： TEST COMPARISON FROM TO DETAILS ============================================================================= ** TOTAL **: 2.13x as fast 1774.4ms +/- 2.7% 833.6ms +/- 2.1% significant ============================================================================= 3d: 2.96x as fast 257.2ms +/- 2.1% 87.0ms <a href='http://www.lingcc.com/2010/01/22/10668/'>[...]</a>
<h3>相关文章：</h3><ul>
<li><a href='http://www.lingcc.com/2009/12/24/10451/' rel='bookmark' title='拥有Nanojit龙芯后端的firefox发布(10年1月14日更新)'>拥有Nanojit龙芯后端的firefox发布(10年1月14日更新)</a></li>
<li><a href='http://www.lingcc.com/2009/12/29/10503/' rel='bookmark' title='GCC初窥'>GCC初窥</a></li>
<li><a href='http://www.lingcc.com/2010/01/05/10588/' rel='bookmark' title='用crossdev装龙芯的n32 gnu交叉工具链'>用crossdev装龙芯的n32 gnu交叉工具链</a></li>
<li><a href='http://www.lingcc.com/2010/01/07/10594/' rel='bookmark' title='使用crossdev安装龙芯的O32 gnu交叉工具链'>使用crossdev安装龙芯的O32 gnu交叉工具链</a></li>
<li><a href='http://www.lingcc.com/2009/12/31/10534/' rel='bookmark' title='Gentoo中的交叉编译利器&#8211;crossdev'>Gentoo中的交叉编译利器&#8211;crossdev</a></li>
<li><a href='http://www.lingcc.com/2010/06/28/10983/' rel='bookmark' title='龙芯N32系统上的Squirrelfish性能'>龙芯N32系统上的Squirrelfish性能</a></li>
</ul>]]></description>
			<content:encoded><![CDATA[<p>严格的说WebKit仅仅是个浏览器核心，采用该核心的浏览器很多，如国内的搜狗浏览器，遨游浏览器。其他的如google的chrome(Windows平台，linux平台下为chromium),epiphany(linux平台下，gnome2.28版本之后),苹果的Safari 都采用了webkit的内核。Firefox则是采用Gecko的内核，这是NetScape公司开发的内核，后来开源，mozilla继续开发。另外，现在还有另外两种常见的浏览器内核，Trident主要用在IE系列上，Presto主要用在Opera上。</p>
<p>这篇文章仅仅针对浏览器处理JavaScript的性能作比较，主要在X86平台和龙芯平台。先来解释一下JavaScript，JavaScript是互联网内较为常用的脚本语言，面向对象，主要在浏览器内解释执行，用于生成动态网页，因为很多语言特性受Java影响，所以叫JavaScript。通过JavaScript，浏览器可以运行服务器想要在访问者终端上运行的一些计算程序，以达到更好的浏览体验。<span id="more-10668"></span></p>
<p>再说说浏览器内核和JavaScript的关系，其实JavaScrip脚本的执行仅仅是浏览器内核的一部分，其他的还有Html语言的解释执行，网页的呈现等等也是内核要做的。之所以这么关心浏览器核心对JavaScript脚本的处理情况，是因为现在的很多应用不再是简单的网页浏览，如gmail，google reader，gooe wave还有一些网页3D特效等等都需要在客户机上作计算，这就需要JavaScript大显身手了。而且越来越多的应用依赖JavaScript，所以现在浏览器对JavaScript的处理速度直接影响着用户体验。目前WebKit的JavaScript引擎SquirrelFish，JavaScript的引擎是SpiderMonkey</p>
<p>目前JavaScript在大多数平台上的处理是靠解释执行的，又因为是动态类型，面向对象。。。，决定了JavaScript执行效率低，所以就诞生了各种针对JavaScript的优化，也有了测试JavaScipt解释器性能的BenchMark，目前常用的是Sunspider和google V8，这篇文章中的对比针对Sunspider测试集。</p>
<p>另外还要说说JIT，Just In time，转换，将部分程序代码直接转换成机器码执行，这种技术在运行时优化中比较常用，JavaScript是解释器，所以JIT在解释器中也是很重要的优化手段。目前X86的webkit和Firefox默认就有JIT支持，但龙芯平台上还没有，本博也是最早对龙芯2F平台有JIT支持的Webkit和firefox  JavaScript引擎作对比的，目前这两个JIT都还没有进入官方的代码库中，感兴趣的朋友可以在下面的前两个链接中找到相关源码。其中webkit的补丁还要做些宏的修改，改动不大。这两个都是从官方源码库checkout出来并修改之后的。其中firefox的JIT部分是由ZSC大牛写出来的，详细的讨论贴和测试结果可以在龙芯论坛看到，见下面的第三个链接。<br />
x86下epiphany(webkit内核)和firefox开了jit之后的性能，如下</p>
<pre id="comment_text_6">
webkit Total:                  833.6ms +/- 2.1%
firefox Total:                 1774.4ms +/- 2.7%</pre>
<p>（测试环境是我的笔记本 intel Pentium t2390,开了频率调节，所以波动较大)、两个差距：</p>
<pre id="console">TEST                   COMPARISON            FROM                 TO             DETAILS

=============================================================================

** TOTAL **:           2.13x as fast     1774.4ms +/- 2.7%   833.6ms +/- 2.1%     significant

=============================================================================

  3d:                  2.96x as fast      257.2ms +/- 2.1%    87.0ms +/- 1.0%     significant
    cube:              3.36x as fast       79.2ms +/- 1.7%    23.6ms +/- 2.9%     significant
    morph:             1.52x as fast       50.4ms +/- 1.4%    33.2ms +/- 3.1%     significant
    raytrace:          4.23x as fast      127.6ms +/- 3.0%    30.2ms +/- 3.4%     significant

  access:              3.26x as fast      237.0ms +/- 4.7%    72.8ms +/- 2.8%     significant
    binary-trees:      8.82x as fast       67.0ms +/- 4.4%     7.6ms +/- 9.0%     significant
    fannkuch:          3.48x as fast       98.2ms +/- 0.6%    28.2ms +/- 3.7%     significant
    nbody:             2.50x as fast       51.4ms +/- 10.3%    20.6ms +/- 3.3%     significant
    nsieve:            -                   20.4ms +/- 56.6%    16.4ms +/- 4.2% 

  bitops:              1.42x as fast       53.8ms +/- 1.9%    38.0ms +/- 0.0%     significant
    3bit-bits-in-byte: *3.10x as slow*      2.0ms +/- 0.0%     6.2ms +/- 9.0%     significant
    bits-in-byte:      -                   11.0ms +/- 8.0%    10.4ms +/- 6.5%
    bitwise-and:       *2.33x as slow*      3.0ms +/- 0.0%     7.0ms +/- 0.0%     significant
    nsieve-bits:       2.62x as fast       37.8ms +/- 1.5%    14.4ms +/- 4.7%     significant

  controlflow:         8.76x as fast       50.8ms +/- 2.0%     5.8ms +/- 9.6%     significant
    recursive:         8.76x as fast       50.8ms +/- 2.0%     5.8ms +/- 9.6%     significant

  crypto:              2.34x as fast       93.8ms +/- 1.7%    40.0ms +/- 2.2%     significant
    aes:               2.57x as fast       54.0ms +/- 3.6%    21.0ms +/- 4.2%     significant
    md5:               2.62x as fast       26.2ms +/- 2.1%    10.0ms +/- 0.0%     significant
    sha1:              1.51x as fast       13.6ms +/- 5.0%     9.0ms +/- 0.0%     significant

  date:                1.87x as fast      275.2ms +/- 2.0%   147.0ms +/- 1.0%     significant
    format-tofte:      2.75x as fast      149.0ms +/- 1.0%    54.2ms +/- 1.0%     significant
    format-xparb:      1.36x as fast      126.2ms +/- 4.0%    92.8ms +/- 1.7%     significant

  math:                1.12x as fast       89.8ms +/- 1.8%    80.2ms +/- 21.7%     significant
    cordic:            2.13x as fast       43.4ms +/- 3.3%    20.4ms +/- 9.2%     significant
    partial-sums:      *1.41x as slow*     34.4ms +/- 2.0%    48.6ms +/- 38.2%     significant
    spectral-norm:     1.07x as fast       12.0ms +/- 0.0%    11.2ms +/- 12.2%     significant

  regexp:              3.73x as fast      125.4ms +/- 15.5%    33.6ms +/- 2.0%     significant
    dna:               3.73x as fast      125.4ms +/- 15.5%    33.6ms +/- 2.0%     significant

  string:              1.80x as fast      591.4ms +/- 3.3%   329.2ms +/- 1.6%     significant
    base64:            *1.24x as slow*     28.4ms +/- 2.4%    35.2ms +/- 1.6%     significant
    fasta:             1.71x as fast      133.0ms +/- 2.3%    78.0ms +/- 4.6%     significant
    tagcloud:          2.81x as fast      169.4ms +/- 3.8%    60.2ms +/- 8.2%     significant
    unpack-code:       1.91x as fast      193.8ms +/- 4.4%   101.6ms +/- 2.7%     significant
    validate-input:    1.23x as fast       66.8ms +/- 5.8%    54.2ms +/- 6.4%     significant</pre>
<p>龙芯上的JIT具体对比数据不便透漏，可以从下面第三个链接中找到第一版发布时的测试数据。这里仅仅给出一个对比。webkit之所以with GUI是使用编译出的迷你小浏览器中测试结果，no GUI是使用测试脚本跑出来的结果。</p>
<pre id="comment_text_4"> Webkit with GUI Total:                  6723.4ms +/- 0.5%
        no GUI   Total:                  6355.8ms +/- 0.5%
 Firfox Total 7000 ms 左右。</pre>
<p>注： 龙芯中的JIT现在还不够成熟，其中Webkit的JIT仅是针对MIPS III做的，没有针对龙芯的特殊优化。</p>
<p>另外，X86中firefox的版本是3.5.7，龙芯中firefox的版本是3.7pre1.WebKit在X86中版本是epiphany的2.28中的版本，龙芯中为SVN中的2010-01-12 r53114。X86运行环境为Gentoo，Gcc4.4.2,Glibc2.11,龙芯运行环境是玲珑一体机，GCC4.3(龙梦修改版）,Glibc2.10。</p>
<p>对比结果可见：X86中WebKit浏览器的性能要明显优于Firefox，达到两倍之多。龙芯相比起来还有些差距，不过相信优化后龙芯的性能会更好。</p>
<p><strong>参考</strong></p>
<p>https://bugs.webkit.org/show_bug.cgi?id=30144</p>
<p>http://dev.lemote.com/code/firefox-3.7-loongson-jit</p>
<p>http://lemote.com/bbs/viewthread.php?tid=26687&#038;extra=page%3D1</p>
<p>http://en.wikipedia.org/wiki/Google_Chrome</p>
<p>http://ineolee.com/pc/several-browser-core-introduction/</p>
<div style=float:left><!-- JiaThis Button BEGIN -->
<div id="jiathis_style_32x32">
	<a class="jiathis_button_qzone"></a>
	<a class="jiathis_button_tsina"></a>
	<a class="jiathis_button_tqq"></a>
	<a class="jiathis_button_renren"></a>
	<a class="jiathis_button_kaixin001"></a>
	<a href="http://www.jiathis.com/share/" class="jiathis jiathis_txt jtico jtico_jiathis" target="_blank"></a>
	<a class="jiathis_counter_style"></a>
</div>
<script type="text/javascript" src="http://v2.jiathis.com/code/jia.js" charset="utf-8"></script>
<!-- JiaThis Button END --></div><p><h3>相关文章：</h3><ul>
<li><a href='http://www.lingcc.com/2009/12/24/10451/' rel='bookmark' title='拥有Nanojit龙芯后端的firefox发布(10年1月14日更新)'>拥有Nanojit龙芯后端的firefox发布(10年1月14日更新)</a></li>
<li><a href='http://www.lingcc.com/2009/12/29/10503/' rel='bookmark' title='GCC初窥'>GCC初窥</a></li>
<li><a href='http://www.lingcc.com/2010/01/05/10588/' rel='bookmark' title='用crossdev装龙芯的n32 gnu交叉工具链'>用crossdev装龙芯的n32 gnu交叉工具链</a></li>
<li><a href='http://www.lingcc.com/2010/01/07/10594/' rel='bookmark' title='使用crossdev安装龙芯的O32 gnu交叉工具链'>使用crossdev安装龙芯的O32 gnu交叉工具链</a></li>
<li><a href='http://www.lingcc.com/2009/12/31/10534/' rel='bookmark' title='Gentoo中的交叉编译利器&#8211;crossdev'>Gentoo中的交叉编译利器&#8211;crossdev</a></li>
<li><a href='http://www.lingcc.com/2010/06/28/10983/' rel='bookmark' title='龙芯N32系统上的Squirrelfish性能'>龙芯N32系统上的Squirrelfish性能</a></li>
</ul></p>]]></content:encoded>
			<wfw:commentRss>http://www.lingcc.com/2010/01/22/10668/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Adobe AIR是什么？</title>
		<link>http://www.lingcc.com/2009/12/13/10285/</link>
		<comments>http://www.lingcc.com/2009/12/13/10285/#comments</comments>
		<pubDate>Sun, 13 Dec 2009 14:03:59 +0000</pubDate>
		<dc:creator>erlv</dc:creator>
				<category><![CDATA[编译技术]]></category>
		<category><![CDATA[Adobe AIR]]></category>
		<category><![CDATA[gcc]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[windows]]></category>
		<category><![CDATA[虚拟机]]></category>
		<category><![CDATA[运行时技术]]></category>

		<guid isPermaLink="false">http://www.lingcc.com/?p=10285</guid>
		<description><![CDATA[Adobe AIR(Adobe Integrated Runtime)是跨平台的运行时系统，是在Apollo的基础上更名的系统。

开发人员可...
<h3>相关文章：</h3><ul>
<li><a href='http://www.lingcc.com/2010/05/25/10951/' rel='bookmark' title='认识静态链接库'>认识静态链接库</a></li>
<li><a href='http://www.lingcc.com/2010/01/22/10668/' rel='bookmark' title='WebKit和Firefox的JavaScript性能对比'>WebKit和Firefox的JavaScript性能对比</a></li>
<li><a href='http://www.lingcc.com/2010/05/12/10931/' rel='bookmark' title='前瞻-拿起SIMD的武器II'>前瞻-拿起SIMD的武器II</a></li>
<li><a href='http://www.lingcc.com/2010/05/04/10878/' rel='bookmark' title='前瞻-主流处理器中的数据并行支持(SIMD)'>前瞻-主流处理器中的数据并行支持(SIMD)</a></li>
<li><a href='http://www.lingcc.com/2010/04/07/10721/' rel='bookmark' title='前瞻-全时优化和LLVM-1'>前瞻-全时优化和LLVM-1</a></li>
<li><a href='http://www.lingcc.com/2009/12/29/10503/' rel='bookmark' title='GCC初窥'>GCC初窥</a></li>
</ul>]]></description>
			<content:encoded><![CDATA[<p>Adobe AIR(Adobe Integrated Runtime)是跨平台的运行时系统，是在Apollo的基础上更名的系统。</p>
<p>开发人员可以通过它将HTML，Ajax Adove Flash和Flex等技术联系在一起，在桌面创建更胖的应用。adobe AIR让用户使用已经熟悉的Adobe工具或者其他的文本编辑器来创建应用，并且能很容易的发布应用。跨平台:windows linux MAC等<br />
传统的浏览器将用户和服务器站点上的内容、应用交互起来。Adobe AIR能够用浏览器中的技术开发桌面应用。简言之，它能将Web应用桌面化。</p>
<p>目前它能很方便的实现桌面集成，包括拖拽，粘帖，任务管理和通知提醒等。并能直接访问本地存储，包括SQL Lite,本地文件读写。<br />
Adobe AIR2.0中新增加的特性：按照类型用默认的程序打开文件，大容量存储设备检测，本地进程API，多点触摸和手势支持等<span id="more-10285"></span><br />
现在Adobe AIR还有很多不足，不支持多线程，LiveCycle基于J2EE服务环境等。虚拟机的下载和安装也不容易。</p>
<p>下图是Adobe  AIR的Runtime 架构：<img class="aligncenter size-full wp-image-10289" title="200798225528693" src="http://www.lingcc.com/wp-content/uploads/2009/12/200798225528693.jpg" alt="200798225528693" width="361" height="267" /></p>
<div style=float:left><!-- JiaThis Button BEGIN -->
<div id="jiathis_style_32x32">
	<a class="jiathis_button_qzone"></a>
	<a class="jiathis_button_tsina"></a>
	<a class="jiathis_button_tqq"></a>
	<a class="jiathis_button_renren"></a>
	<a class="jiathis_button_kaixin001"></a>
	<a href="http://www.jiathis.com/share/" class="jiathis jiathis_txt jtico jtico_jiathis" target="_blank"></a>
	<a class="jiathis_counter_style"></a>
</div>
<script type="text/javascript" src="http://v2.jiathis.com/code/jia.js" charset="utf-8"></script>
<!-- JiaThis Button END --></div><p><h3>相关文章：</h3><ul>
<li><a href='http://www.lingcc.com/2010/05/25/10951/' rel='bookmark' title='认识静态链接库'>认识静态链接库</a></li>
<li><a href='http://www.lingcc.com/2010/01/22/10668/' rel='bookmark' title='WebKit和Firefox的JavaScript性能对比'>WebKit和Firefox的JavaScript性能对比</a></li>
<li><a href='http://www.lingcc.com/2010/05/12/10931/' rel='bookmark' title='前瞻-拿起SIMD的武器II'>前瞻-拿起SIMD的武器II</a></li>
<li><a href='http://www.lingcc.com/2010/05/04/10878/' rel='bookmark' title='前瞻-主流处理器中的数据并行支持(SIMD)'>前瞻-主流处理器中的数据并行支持(SIMD)</a></li>
<li><a href='http://www.lingcc.com/2010/04/07/10721/' rel='bookmark' title='前瞻-全时优化和LLVM-1'>前瞻-全时优化和LLVM-1</a></li>
<li><a href='http://www.lingcc.com/2009/12/29/10503/' rel='bookmark' title='GCC初窥'>GCC初窥</a></li>
</ul></p>]]></content:encoded>
			<wfw:commentRss>http://www.lingcc.com/2009/12/13/10285/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Gcc和Open64中的-fPIC选项</title>
		<link>http://www.lingcc.com/2009/11/20/10065/</link>
		<comments>http://www.lingcc.com/2009/11/20/10065/#comments</comments>
		<pubDate>Fri, 20 Nov 2009 11:07:13 +0000</pubDate>
		<dc:creator>erlv</dc:creator>
				<category><![CDATA[GCC]]></category>
		<category><![CDATA[open64]]></category>
		<category><![CDATA[编译技术]]></category>
		<category><![CDATA[编译理论实践和应用]]></category>
		<category><![CDATA[amd]]></category>
		<category><![CDATA[debian]]></category>
		<category><![CDATA[gcc]]></category>
		<category><![CDATA[gentoo]]></category>
		<category><![CDATA[N64]]></category>
		<category><![CDATA[Open64]]></category>
		<category><![CDATA[编译器]]></category>
		<category><![CDATA[运行时技术]]></category>
		<category><![CDATA[选项学习]]></category>
		<category><![CDATA[链接]]></category>

		<guid isPermaLink="false">http://lingcc.net/?p=10065</guid>
		<description><![CDATA[选项 -fPIC PIC是Position-Independent Code的缩写。在计算机系统中，PIC和PIE(Position-Independent Executable)是可以在主存中不同位置执行的目标代码。PIC经常被用在共享库中，这样就能将相同的库代码为每个程序映射到一个位置，不用担心覆盖掉其他程序或共享库。 要想实现位置无关，代码必须通过特定的方式编写、编译才行。比如对于固定地址的绝对跳转指令，就需要使用相对应的相对跳转指令代替，相对位置的计算通过对指令计数器的计算得到。在某些特定的体系结构上(如AMD64),共享库就必须支持PIC。 另外位置独立还需要与重分配(reallocate)区分，后者是指在计算机中将符号因引用或者库的名字用主存中的可用地址代替。虽然能在运行时通过装载器(loader)完成，但通常是在编译阶段由连接器(linker)完成。编译器或者汇编器通常会生成从0位置开始的可执行代码，在代码运行之前，这些相对地址将修改为正确的运行时地址。 通常congfigure能够检测出编译器是否支持-fPIC，是通过编译一个小程序，并且检查stderr输出实现的。若此时编译器输出了任何的警告，就视为不支持。此时如果用户在CFLAGS或者CXXFLAGS中指定了一个错误的flag，那编译任何程序都会出警告，于是就会被判为-fPIC不可用。 现在我们就可以考虑以下三种情况需要-fPIC 不需要动态链接库的可执行程序： 因为通常可执行程序会被装载到固定的地址，并从此处开始运行，所以普通可执行程序不需要-fPIC 静态链接库：相当于一个大.o文件结合，又被称作可充分配对象。它们包含了一些可将它们在内存中改变位置的信息(使用重分配移动),所以静态链接库也不需要-fPIC 动态链接库：因为动态链接库就是为了实现位置无关，所以需要使用-fPIC. 参考文献 http://www.gentoo.org/proj/en/base/amd64/howtos/index.xml?part=1&#38;chap=3 http://lists.debian.org/debian-mentors/2002/03/msg00165.html 相关文章： GCC初窥 GCC中的pie和fpie选项 Open64课程&#8211;付诸实践(Practical Matters) 前瞻-全时优化和LLVM-1 Open64课程&#8212;代码生成(CG) open64课程&#8211;过程间分析优化(IPA)
<h3>相关文章：</h3><ul>
<li><a href='http://www.lingcc.com/2009/12/29/10503/' rel='bookmark' title='GCC初窥'>GCC初窥</a></li>
<li><a href='http://www.lingcc.com/2010/01/08/10609/' rel='bookmark' title='GCC中的pie和fpie选项'>GCC中的pie和fpie选项</a></li>
<li><a href='http://www.lingcc.com/2009/12/27/10464/' rel='bookmark' title='Open64课程&#8211;付诸实践(Practical Matters)'>Open64课程&#8211;付诸实践(Practical Matters)</a></li>
<li><a href='http://www.lingcc.com/2010/04/07/10721/' rel='bookmark' title='前瞻-全时优化和LLVM-1'>前瞻-全时优化和LLVM-1</a></li>
<li><a href='http://www.lingcc.com/2009/12/16/10317/' rel='bookmark' title='Open64课程&#8212;代码生成(CG)'>Open64课程&#8212;代码生成(CG)</a></li>
<li><a href='http://www.lingcc.com/2009/12/14/10295/' rel='bookmark' title='open64课程&#8211;过程间分析优化(IPA)'>open64课程&#8211;过程间分析优化(IPA)</a></li>
</ul>]]></description>
			<content:encoded><![CDATA[<p STYLE="margin-bottom: 0cm">选项 <font FACE="Times New Roman, serif"><span LANG="en-US">-fPIC</span></font></p>
<p STYLE="margin-bottom: 0cm">   <font FACE="Times New Roman, serif"><span LANG="en-US">PIC</span></font>是<font FACE="Times New Roman, serif"><span LANG="en-US">Position-Independent<br />
Code</span></font>的缩写。在计算机系统中，<font FACE="Times New Roman, serif"><span LANG="en-US">PIC</span></font>和<font FACE="Times New Roman, serif"><span LANG="en-US">PIE(Position-Independent<br />
Executable)</span></font>是可以在主存中不同位置执行的目标代码。<font FACE="Times New Roman, serif"><span LANG="en-US">PIC</span></font>经常被用在共享库中，这样就能将相同的库代码为每个程序映射到一个位置，不用担心覆盖掉其他程序或共享库。</p>
<p STYLE="margin-bottom: 0cm">
要想实现位置无关，代码必须通过特定的方式编写、编译才行。比如对于固定地址的绝对跳转指令，就需要使用相对应的相对跳转指令代替，相对位置的计算通过对指令计数器的计算得到。在某些特定的体系结构上<font FACE="Times New Roman, serif"><span LANG="en-US">(</span></font>如<font FACE="Times New Roman, serif"><span LANG="en-US">AMD64),</span></font>共享库就必须支持<font FACE="Times New Roman, serif"><span LANG="en-US">PIC</span></font>。</p>
<p><span id="more-10065"></span></p>
<p STYLE="margin-bottom: 0cm">
另外位置独立还需要与重分配<font FACE="Times New Roman, serif"><span LANG="en-US">(reallocate)</span></font>区分，后者是指在计算机中将符号因引用或者库的名字用主存中的可用地址代替。虽然能在运行时通过装载器<font FACE="Times New Roman, serif"><span LANG="en-US">(loader)</span></font>完成，但通常是在编译阶段由连接器<font FACE="Times New Roman, serif"><span LANG="en-US">(linker)</span></font>完成。编译器或者汇编器通常会生成从<font FACE="Times New Roman, serif"><span LANG="en-US">0</span></font>位置开始的可执行代码，在代码运行之前，这些相对地址将修改为正确的运行时地址。</p>
<p STYLE="margin-bottom: 0cm">
通常<font FACE="Times New Roman, serif"><span LANG="en-US">congfigure</span></font>能够检测出编译器是否支持<font FACE="Times New Roman, serif"><span LANG="en-US">-fPIC</span></font>，是通过编译一个小程序，并且检查<font FACE="Times New Roman, serif"><span LANG="en-US">stderr</span></font>输出实现的。若此时编译器输出了任何的警告，就视为不支持。此时如果用户在<font FACE="Times New Roman, serif"><span LANG="en-US">CFLAGS</span></font>或者<font FACE="Times New Roman, serif"><span LANG="en-US">CXXFLAGS</span></font>中指定了一个错误的<font FACE="Times New Roman, serif"><span LANG="en-US">flag</span></font>，那编译任何程序都会出警告，于是就会被判为<font FACE="Times New Roman, serif"><span LANG="en-US">-fPIC</span></font>不可用。</p>
<p STYLE="margin-bottom: 0cm">   现在我们就可以考虑以下三种情况需要<font FACE="Times New Roman, serif"><span LANG="en-US">-fPIC</span></font></p>
<ol>
<li>
<p STYLE="margin-bottom: 0cm">不需要动态链接库的可执行程序：<br />
	因为通常可执行程序会被装载到固定的地址，并从此处开始运行，所以普通可执行程序不需要<font FACE="Times New Roman, serif"><span LANG="en-US">-fPIC</span></font></p>
<li>
<p STYLE="margin-bottom: 0cm">静态链接库：相当于一个大<font FACE="Times New Roman, serif"><span LANG="en-US">.o</span></font>文件结合，又被称作可充分配对象。它们包含了一些可将它们在内存中改变位置的信息<font FACE="Times New Roman, serif"><span LANG="en-US">(</span></font>使用重分配移动<font FACE="Times New Roman, serif"><span LANG="en-US">),</span></font>所以静态链接库也不需要<font FACE="Times New Roman, serif"><span LANG="en-US">-fPIC</span></font></p>
<li>
<p STYLE="margin-bottom: 0cm">动态链接库：因为动态链接库就是为了实现位置无关，所以需要使用<font FACE="Times New Roman, serif"><span LANG="en-US">-fPIC.</span></font></p>
</ol>
<p STYLE="margin-bottom: 0cm">
</p>
<p STYLE="margin-bottom: 0cm">参考文献</p>
<ul>
<li>
<p STYLE="margin-bottom: 0cm"><font FACE="Times New Roman, serif"><span LANG="en-US"><a HREF="http://www.gentoo.org/proj/en/base/amd64/howtos/index.xml?part=1&amp;chap=3">http://www.gentoo.org/proj/en/base/amd64/howtos/index.xml?part=1&amp;chap=3</a></span></font></p>
<li>
<p STYLE="margin-bottom: 0cm"><font FACE="Times New Roman, serif"><span LANG="en-US"><a HREF="http://lists.debian.org/debian-mentors/2002/03/msg00165.html">http://lists.debian.org/debian-mentors/2002/03/msg00165.html</a></span></font></p>
<div style=float:left><!-- JiaThis Button BEGIN -->
<div id="jiathis_style_32x32">
	<a class="jiathis_button_qzone"></a>
	<a class="jiathis_button_tsina"></a>
	<a class="jiathis_button_tqq"></a>
	<a class="jiathis_button_renren"></a>
	<a class="jiathis_button_kaixin001"></a>
	<a href="http://www.jiathis.com/share/" class="jiathis jiathis_txt jtico jtico_jiathis" target="_blank"></a>
	<a class="jiathis_counter_style"></a>
</div>
<script type="text/javascript" src="http://v2.jiathis.com/code/jia.js" charset="utf-8"></script>
<!-- JiaThis Button END --></div><p><h3>相关文章：</h3><ul>
<li><a href='http://www.lingcc.com/2009/12/29/10503/' rel='bookmark' title='GCC初窥'>GCC初窥</a></li>
<li><a href='http://www.lingcc.com/2010/01/08/10609/' rel='bookmark' title='GCC中的pie和fpie选项'>GCC中的pie和fpie选项</a></li>
<li><a href='http://www.lingcc.com/2009/12/27/10464/' rel='bookmark' title='Open64课程&#8211;付诸实践(Practical Matters)'>Open64课程&#8211;付诸实践(Practical Matters)</a></li>
<li><a href='http://www.lingcc.com/2010/04/07/10721/' rel='bookmark' title='前瞻-全时优化和LLVM-1'>前瞻-全时优化和LLVM-1</a></li>
<li><a href='http://www.lingcc.com/2009/12/16/10317/' rel='bookmark' title='Open64课程&#8212;代码生成(CG)'>Open64课程&#8212;代码生成(CG)</a></li>
<li><a href='http://www.lingcc.com/2009/12/14/10295/' rel='bookmark' title='open64课程&#8211;过程间分析优化(IPA)'>open64课程&#8211;过程间分析优化(IPA)</a></li>
</ul></p>]]></content:encoded>
			<wfw:commentRss>http://www.lingcc.com/2009/11/20/10065/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>今日记录-091117</title>
		<link>http://www.lingcc.com/2009/11/17/9999/</link>
		<comments>http://www.lingcc.com/2009/11/17/9999/#comments</comments>
		<pubDate>Tue, 17 Nov 2009 14:06:00 +0000</pubDate>
		<dc:creator>erlv</dc:creator>
				<category><![CDATA[编译技术]]></category>
		<category><![CDATA[MIPS]]></category>
		<category><![CDATA[整点]]></category>
		<category><![CDATA[编程技术]]></category>
		<category><![CDATA[编译器]]></category>
		<category><![CDATA[运行时技术]]></category>

		<guid isPermaLink="false">http://lingcc.net/blog/?p=9999</guid>
		<description><![CDATA[1，程序的run-time environment中 stack和heap 一般是相向增长，那么os/编译器是如何确定程序的运行时内存大小的呢？ 2，static修饰的变量是静态变量，全局的静态变量将保存在Runtime Environment的静态变量区域中，局部的静态变量如何保存？保存在活动记录的栈里，像其他局部变量一样？ 全局的静态变量表示仅在此文件中可用，当函数前增加static时，也是一样的。 局部的静态变量是在函数中被声明的，尽在此函数第一次被调用时初始化为0，且在此函数重新被调用时将不再初始化。 &#160;&#160; 不管是全局还是局部的静态变量都将存储在内存中的Data&#160; segment(Code segment,Data segment和stack segment 是c++ runtime的三大区)中，它们的生存期直到程序退出，但是它们的作用域尽在声明它的函数内部。当是全局静态变量时，它的作用于就是声明它的那个文件。 当两个不同的函数中声明了名称相同的静态变量时，编译器将会把它们当作不同的变量来处理，方式就是做别名处理。这样两个静态变量将完全不受影响。 3，Runtime Environment的活动记录中，保存着传入函数的参数，返回值，被调用时的机器状态，callee的数据等等。在mips架构的机器中，预定使用$ra($31)寄存器来保存返回值信息，这个返回值信息是什么？如果是值的话，难道$31寄存器还要有整点和浮点两个寄存器？难道其他的寄存器，如$fp($30,frame point),$sp($29,stack pointer)也是一样？ 4，Runtime中，活动记录以栈的形式存放在内存中，那么gdb的backtrace是如何实现的？ 相关文章： 前瞻-全时优化和LLVM-1 GCC几个选项学习 前瞻-拿起SIMD的武器II 前瞻-LLVM大事记(2004-2010) Adobe AIR是什么？ 调用栈-你还记得吗？
<h3>相关文章：</h3><ul>
<li><a href='http://www.lingcc.com/2010/04/07/10721/' rel='bookmark' title='前瞻-全时优化和LLVM-1'>前瞻-全时优化和LLVM-1</a></li>
<li><a href='http://www.lingcc.com/2011/06/27/11679/' rel='bookmark' title='GCC几个选项学习'>GCC几个选项学习</a></li>
<li><a href='http://www.lingcc.com/2010/05/12/10931/' rel='bookmark' title='前瞻-拿起SIMD的武器II'>前瞻-拿起SIMD的武器II</a></li>
<li><a href='http://www.lingcc.com/2010/04/30/10822/' rel='bookmark' title='前瞻-LLVM大事记(2004-2010)'>前瞻-LLVM大事记(2004-2010)</a></li>
<li><a href='http://www.lingcc.com/2009/12/13/10285/' rel='bookmark' title='Adobe AIR是什么？'>Adobe AIR是什么？</a></li>
<li><a href='http://www.lingcc.com/2010/09/27/11251/' rel='bookmark' title='调用栈-你还记得吗？'>调用栈-你还记得吗？</a></li>
</ul>]]></description>
			<content:encoded><![CDATA[<p>1，程序的run-time environment中 stack和heap 一般是相向增长，那么os/编译器是如何确定程序的运行时内存大小的呢？</p>
<p>
2，static修饰的变量是静态变量，全局的静态变量将保存在Runtime Environment的静态变量区域中，局部的静态变量如何保存？保存在活动记录的栈里，像其他局部变量一样？ <br />
<span id="more-9999"></span><br />
全局的静态变量表示仅在此文件中可用，当函数前增加static时，也是一样的。<br />
局部的静态变量是在函数中被声明的，尽在此函数第一次被调用时初始化为0，且在此函数重新被调用时将不再初始化。<br />
<span><span class="tdvamseel">&#160;&#160; 不管是全局还是局部的静态变量都将存储在内存中的Data&#160; segment(Code segment,Data segment和stack segment 是c++ runtime的三大区)中，它们的生存期直到程序退出，但是它们的作用域尽在声明它的函数内部。当是全局静态变量时，它的作用于就是声明它的那个文件。<br />
当两个不同的函数中声明了名称相同的静态变量时，编译器将会把它们当作不同的变量来处理，方式就是做别名处理。这样两个静态变量将完全不受影响。<br />
</span></span><br />
3，Runtime Environment的活动记录中，保存着传入函数的参数，返回值，被调用时的机器状态，callee的数据等等。在mips架构的机器中，预定使用$ra($31)寄存器来保存返回值信息，这个返回值信息是什么？如果是值的话，难道$31寄存器还要有整点和浮点两个寄存器？难道其他的寄存器，如$fp($30,frame point),$sp($29,stack pointer)也是一样？</p>
<p>
4，Runtime中，活动记录以栈的形式存放在内存中，那么gdb的backtrace是如何实现的？</p>
<div style=float:left><!-- JiaThis Button BEGIN -->
<div id="jiathis_style_32x32">
	<a class="jiathis_button_qzone"></a>
	<a class="jiathis_button_tsina"></a>
	<a class="jiathis_button_tqq"></a>
	<a class="jiathis_button_renren"></a>
	<a class="jiathis_button_kaixin001"></a>
	<a href="http://www.jiathis.com/share/" class="jiathis jiathis_txt jtico jtico_jiathis" target="_blank"></a>
	<a class="jiathis_counter_style"></a>
</div>
<script type="text/javascript" src="http://v2.jiathis.com/code/jia.js" charset="utf-8"></script>
<!-- JiaThis Button END --></div><p><h3>相关文章：</h3><ul>
<li><a href='http://www.lingcc.com/2010/04/07/10721/' rel='bookmark' title='前瞻-全时优化和LLVM-1'>前瞻-全时优化和LLVM-1</a></li>
<li><a href='http://www.lingcc.com/2011/06/27/11679/' rel='bookmark' title='GCC几个选项学习'>GCC几个选项学习</a></li>
<li><a href='http://www.lingcc.com/2010/05/12/10931/' rel='bookmark' title='前瞻-拿起SIMD的武器II'>前瞻-拿起SIMD的武器II</a></li>
<li><a href='http://www.lingcc.com/2010/04/30/10822/' rel='bookmark' title='前瞻-LLVM大事记(2004-2010)'>前瞻-LLVM大事记(2004-2010)</a></li>
<li><a href='http://www.lingcc.com/2009/12/13/10285/' rel='bookmark' title='Adobe AIR是什么？'>Adobe AIR是什么？</a></li>
<li><a href='http://www.lingcc.com/2010/09/27/11251/' rel='bookmark' title='调用栈-你还记得吗？'>调用栈-你还记得吗？</a></li>
</ul></p>]]></content:encoded>
			<wfw:commentRss>http://www.lingcc.com/2009/11/17/9999/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

