<?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; 甘驰 (Intel)</title>
	<atom:link href="http://software.intel.com/zh-cn/blogs/author/334076/feed/" rel="self" type="application/rss+xml" />
	<link>http://software.intel.com/zh-cn/blogs</link>
	<description></description>
	<lastBuildDate>Mon, 28 May 2012 13:40:23 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.3</generator>
		<item>
		<title>Intel® Parallel VTune™ Amplifier XE的信息采集方法</title>
		<link>http://software.intel.com/zh-cn/blogs/2011/03/02/intel-parallel-vtune-amplifier-xe-3/</link>
		<comments>http://software.intel.com/zh-cn/blogs/2011/03/02/intel-parallel-vtune-amplifier-xe-3/#comments</comments>
		<pubDate>Wed, 02 Mar 2011 06:36:07 +0000</pubDate>
		<dc:creator>甘驰 (Intel)</dc:creator>
				<category><![CDATA[并行计算]]></category>
		<category><![CDATA[英特尔信息技术峰会]]></category>
		<category><![CDATA[软件开发工具]]></category>

		<guid isPermaLink="false">http://software.intel.com/zh-cn/blogs/2011/03/02/intel-parallel-vtune-amplifier-xe-3/</guid>
		<description><![CDATA[Intel® Parallel VTune™ Amplifier XE的信息采集方法]]></description>
			<content:encoded><![CDATA[<p>VTune Amplifier有两种信息采集方式，实现的技术也各有不同。</p>
<p><strong>User-mode sampling and tracing collection</strong></p>
<p>对于由VTune Amplifier启动的程序，user-mode sampling and tracing collector （简称软采样器）定时中断它，采集IP和调用顺序，存于一数据文件，最后被统计并报告热点。Intel Thread Checker在被分析程序的源代码或执行码插入侦测代码，截取锁、信号量等信息，但会产出较大的过载，VTune Amplifier中使用Pin技术（<a href="http://www.pintool.org/">http://www.pintool.org/</a>）从而提高了采集信息的效率。</p>
<p>对于非VTune Amplifier启动的程序，如后台服务，PMU计数器溢出导致sampling driver让该程序产生一个单步debugging异常，软采样器利用debug机制采集信息。软采样器每十毫秒采样一次的过载为5%CPU时间</p>
<p>本表告知三个User-mode sampling and tracing collection的子类，即Hotspot, Concurrency and Locks&amp;Waits，以及它们分别采集哪些信息。</p>
<table border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td width="253" valign="top"> </td>
<td width="85" valign="top"><strong>Hotspot</strong></td>
<td width="113" valign="top"><strong>Concurrency</strong></td>
<td width="117" valign="top"><strong>Locks and waits</strong></td>
</tr>
<tr>
<td width="253" valign="top">CPU sampling Interval(MS)</td>
<td width="85" valign="top">10</td>
<td width="113" valign="top">10</td>
<td width="117" valign="top">10</td>
</tr>
<tr>
<td width="253" valign="top">Detect context switches --Yes/No</td>
<td width="85" valign="top">No</td>
<td width="113" valign="top">Yes</td>
<td width="117" valign="top">Yes</td>
</tr>
<tr>
<td width="253" valign="top">Collect CPU sampling data--No/with stacks/without stack</td>
<td width="85" valign="top">With</td>
<td width="113" valign="top">With</td>
<td width="117" valign="top">Without</td>
</tr>
<tr>
<td width="253" valign="top">Collect signaling API data--No/with stacks/without stack</td>
<td width="85" valign="top">No</td>
<td width="113" valign="top">With</td>
<td width="117" valign="top">With</td>
</tr>
<tr>
<td width="253" valign="top">Collect Sync API data--No/with stacks/without stack</td>
<td width="85" valign="top">No</td>
<td width="113" valign="top">With</td>
<td width="117" valign="top">With</td>
</tr>
<tr>
<td width="253" valign="top">Collect I/O API data--No/with stacks/without stack</td>
<td width="85" valign="top">No</td>
<td width="113" valign="top">With</td>
<td width="117" valign="top">With</td>
</tr>
<tr>
<td width="253" valign="top">Stack Unwinding mode--During/after collection</td>
<td width="85" valign="top">After</td>
<td width="113" valign="top">After</td>
<td width="117" valign="top">After</td>
</tr>
<tr>
<td width="253" valign="top">Collect timeline data --Yes/No</td>
<td width="85" valign="top">Yes</td>
<td width="113" valign="top">Yes</td>
<td width="117" valign="top">Yes</td>
</tr>
</tbody>
</table>
<p><strong>Hardware Event-based Sampling Collection</strong></p>
<p>通过PMU计数器溢出导致中断，VTune Amplifier的Hardware event-based sampling collector(简称硬采样器)响应中断并采集当前系统中运行程序的IP，最后统计这些IP信息报告相关代码段。硬采样器每一毫秒采样一次的过载为2%CPU时间。</p>
]]></content:encoded>
			<wfw:commentRss>http://software.intel.com/zh-cn/blogs/2011/03/02/intel-parallel-vtune-amplifier-xe-3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Intel® Parallel VTune™ Amplifier XE的基础</title>
		<link>http://software.intel.com/zh-cn/blogs/2011/02/23/intel-parallel-vtune-amplifier-xe-2/</link>
		<comments>http://software.intel.com/zh-cn/blogs/2011/02/23/intel-parallel-vtune-amplifier-xe-2/#comments</comments>
		<pubDate>Wed, 23 Feb 2011 07:49:15 +0000</pubDate>
		<dc:creator>甘驰 (Intel)</dc:creator>
				<category><![CDATA[并行计算]]></category>
		<category><![CDATA[软件开发工具]]></category>

		<guid isPermaLink="false">http://software.intel.com/zh-cn/blogs/2011/02/23/intel-parallel-vtune-amplifier-xe-2/</guid>
		<description><![CDATA[Amplifier每个项目以分析类型/结果为基本单元。在Project Properties弹出框中，设定、修改被测程序，参数，是Native或Managed Code（.Net）等。在New Amplifier XE Result TAB内选定分析类型，设定相应参数，如硬件事件类型等。然后按Start键启动分析。   分析结束，产生一个新TAB，本例中r002ge, r代表result，002是分析序号，ge代表分析类型General Exploration。cc 代表Concurrency, lw代表Lock &#38; Wait, hs代表Hotspots。TAB有 Analysis Target：即设定的Project Properties Analysis Type：即设定的分析类型，及其参数 Collection Log：收集、分析数据是否成功，及其相应信息。 Summary: 收集到的信息的汇总报告 Button-up或 Top-down: 各种具体显示数据的方法。  ]]></description>
			<content:encoded><![CDATA[<p>Amplifier每个项目以分析类型/结果为基本单元。在<strong>Project Properties</strong><strong>弹出框</strong>中，设定、修改被测程序，参数，是Native或Managed Code（.Net）等。在<strong>New Amplifier XE Result TAB</strong>内选定分析类型，设定相应参数，如硬件事件类型等。然后按<strong>Start</strong><strong>键</strong>启动分析。</p>
<p> <a href="http://software.intel.com/zh-cn/blogs/wordpress/wp-content/uploads/2011/02/GE4.jpg"><img class="alignnone size-large wp-image-400006822" src="http://software.intel.com/zh-cn/blogs/wordpress/wp-content/uploads/2011/02/GE4-1024x640.jpg" alt="" width="1024" height="640" /></a></p>
<p>分析结束，产生一个新TAB，本例中r002ge, r代表result，002是分析序号，ge代表分析类型General Exploration。cc 代表Concurrency, lw代表Lock &amp; Wait, hs代表Hotspots。TAB有</p>
<ul>
<li>Analysis Target：即设定的Project Properties</li>
<li>Analysis Type：即设定的分析类型，及其参数</li>
<li>Collection Log：收集、分析数据是否成功，及其相应信息。</li>
<li>Summary: 收集到的信息的汇总报告</li>
<li>Button-up或 Top-down: 各种具体显示数据的方法。</li>
</ul>
<p> <a href="http://software.intel.com/zh-cn/blogs/wordpress/wp-content/uploads/2011/02/GE1.jpg"><img class="alignnone size-large wp-image-400006823" src="http://software.intel.com/zh-cn/blogs/wordpress/wp-content/uploads/2011/02/GE1-1024x640.jpg" alt="" width="1024" height="640" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://software.intel.com/zh-cn/blogs/2011/02/23/intel-parallel-vtune-amplifier-xe-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Intel® Parallel VTune™ Amplifier XE的改进</title>
		<link>http://software.intel.com/zh-cn/blogs/2011/02/23/intel-parallel-vtune-amplifier-xe/</link>
		<comments>http://software.intel.com/zh-cn/blogs/2011/02/23/intel-parallel-vtune-amplifier-xe/#comments</comments>
		<pubDate>Wed, 23 Feb 2011 06:53:41 +0000</pubDate>
		<dc:creator>甘驰 (Intel)</dc:creator>
				<category><![CDATA[其他]]></category>

		<guid isPermaLink="false">http://software.intel.com/zh-cn/blogs/2011/02/23/intel-parallel-vtune-amplifier-xe/</guid>
		<description><![CDATA[  1．  Intel® VTune™ Performance Analyzer只能对整个系统进行采样。Amplifier XE增加了启动某个程序并只对其采样，和只对某个已运行程序采样。 2．  被采样的硬件事件种类数量受制于CPU的PMU(Performance Monitor Unit)，当采集超过4种数量时，老VTune会执行该程序多次，因而费时颇多。Amplifier XE能在一次执行中采集所有用户选定的事件。 3．  下图中Hardware Event数量能按Timeline展开，告知某种事件在何时频繁发生。在篮圈中下拉框里，用户可选定显示某种事件，老VTune只能告知整个运行时间内的某事件总数。在红圈中下拉框里，用户可选定显示某个模块，进程或线程。]]></description>
			<content:encoded><![CDATA[<p> </p>
<p>1．  Intel® VTune™ Performance Analyzer只能对整个系统进行采样。Amplifier XE增加了启动某个程序并只对其采样，和只对某个已运行程序采样。</p>
<p>2．  被采样的硬件事件种类数量受制于CPU的PMU(Performance Monitor Unit)，当采集超过4种数量时，老VTune会执行该程序多次，因而费时颇多。Amplifier XE能在一次执行中采集所有用户选定的事件。</p>
<p>3．  下图中Hardware Event数量能按Timeline展开，告知某种事件在何时频繁发生。在篮圈中下拉框里，用户可选定显示某种事件，老VTune只能告知整个运行时间内的某事件总数。在红圈中下拉框里，用户可选定显示某个模块，进程或线程。</p>
<p><a href="http://software.intel.com/zh-cn/blogs/wordpress/wp-content/uploads/2011/02/GE3.jpg"><img class="alignnone size-large wp-image-400006817" src="http://software.intel.com/zh-cn/blogs/wordpress/wp-content/uploads/2011/02/GE3-1024x640.jpg" alt="" width="1024" height="640" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://software.intel.com/zh-cn/blogs/2011/02/23/intel-parallel-vtune-amplifier-xe/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Intel(R) Parallel VTune(TM) Amplifier XE中Lock-wait分析的Timeline图解</title>
		<link>http://software.intel.com/zh-cn/blogs/2011/02/23/intelr-parallel-vtunetm-amplifier-xelock-waittimeline/</link>
		<comments>http://software.intel.com/zh-cn/blogs/2011/02/23/intelr-parallel-vtunetm-amplifier-xelock-waittimeline/#comments</comments>
		<pubDate>Wed, 23 Feb 2011 02:36:07 +0000</pubDate>
		<dc:creator>甘驰 (Intel)</dc:creator>
				<category><![CDATA[并行计算]]></category>
		<category><![CDATA[软件开发工具]]></category>

		<guid isPermaLink="false">http://software.intel.com/zh-cn/blogs/2011/02/23/intelr-parallel-vtunetm-amplifier-xelock-waittimeline/</guid>
		<description><![CDATA[Intel Parallel Amplifier XE中Lock-wait分析的Timeline图解解释]]></description>
			<content:encoded><![CDATA[<p>Lock-wait分析是Amplifer XE中的一项重要功能，它报告一个程序内线程锁操作和相互等待的状况，timeline图解则能帮用户具体连接每次锁所有权的交换，以及该次等待的时间。</p>
<p><a href="http://software.intel.com/zh-cn/blogs/wordpress/wp-content/uploads/2011/02/LW2.jpg"></a> <a href="http://software.intel.com/zh-cn/blogs/wordpress/wp-content/uploads/2011/02/LW2.jpg"><img class="alignnone size-large wp-image-400006812" src="http://software.intel.com/zh-cn/blogs/wordpress/wp-content/uploads/2011/02/LW2-1024x640.jpg" alt="" width="1024" height="640" /></a></p>
<p>上图的上半部，列出源代码，标明该锁的等待时间等，直观易懂。下半部则是timeline图解，不解释，估计难以理解。Threads区域列出程序中所有线程，本例中有4个线程。Thread Concurrency区域中列出当时用几个线程在工作。</p>
<p>当光标移到某根表示锁所有权传递（transition）的黄线，它被变成红色以突出，同时弹出窗口。窗口上部的数据表示哪两个线程中的那两行代码间传递锁，下部数据表示光标所在线程的当前的状态，本例中光标在第二行（Thread Ox109c），浅绿表示它在等待状态，本次等待从1.685s开始，等52.564秒。</p>
<p> <a href="http://software.intel.com/zh-cn/blogs/wordpress/wp-content/uploads/2011/02/LW1.jpg"><img class="alignnone size-large wp-image-400006811" src="http://software.intel.com/zh-cn/blogs/wordpress/wp-content/uploads/2011/02/LW1-1024x640.jpg" alt="" width="1024" height="640" /></a></p>
<p>上图光标移到第一行（WinMainCRTStartup 0x758）后，数据显示该线程从31.227s开始，等了0.017s。<br />
按红圈提示button，则将程序运行完整过程压缩于该窗口，如这时你看到threads区域几乎被表示transition的黄线覆盖，那程序很可能有锁及等待造成的性能问题。</p>
]]></content:encoded>
			<wfw:commentRss>http://software.intel.com/zh-cn/blogs/2011/02/23/intelr-parallel-vtunetm-amplifier-xelock-waittimeline/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>关于科学计算中的数值误差问题</title>
		<link>http://software.intel.com/zh-cn/blogs/2010/01/26/400003305/</link>
		<comments>http://software.intel.com/zh-cn/blogs/2010/01/26/400003305/#comments</comments>
		<pubDate>Tue, 26 Jan 2010 07:51:28 +0000</pubDate>
		<dc:creator>甘驰 (Intel)</dc:creator>
				<category><![CDATA[并行计算]]></category>
		<category><![CDATA[英特尔® 软件网络 2.0]]></category>
		<category><![CDATA[HPC 精度 误差]]></category>

		<guid isPermaLink="false">http://software.intel.com/zh-cn/blogs/2010/01/26/400003305/</guid>
		<description><![CDATA[最近看到有开发HPC应用的程序员反映换了编译器后，新程序的结果不正确。我不禁想起20年前在16位IBM PC AT/XT台式机上开发CAD/CAM程序, 程序在计算边界状况时，如两圆柱的轴夹角为1分求交线，结果经常匪夷所思，都是精度惹得祸。进入64bit时代同样的问题仍然存在，单次运算的精度提高了，但HPC程序中的大量的迭代计算，累积了误差，导致结果不同。我读了Intel同事的文章（http://software.intel.com/en-us/articles/consistency-of-floating-point-results-using-the-intel-compiler），略有所得，与大家分享。 人们要求结果的复现性有以下几方面， -同一程序，同一数据集，执行若干次的结果相同（近） -同一代码，不同编译选项产生的程序，相同的数据集，执行的结果相同（近） -同一代码，不同编译器产生的程序，相同的数据集，执行的结果相同（近） -同一代码，相同的数据集，在不同架构的CPU上执行的结果相同（近） 最好运行速度也要快。这些要求有时是相互矛盾的。让我们先分析计算结果有差别的原因，注意这里我用了差别，而不是误差。 首先，通常十进制的浮点数用二进制数表示时就有误差，便有了‘原罪’。 其二，计算机运算是不符合结合律的，如A+B+C不一定等于A+(B+C)。当A= -B且C为极小值时，A+B+C=C，但A+(B+C)=0，极小值C和B相加时由于精度限制，被忽略了或者说表示B的有效位不能包含C的值；但A+B=0,再加C后，结果为C。当你多线程或多进程化程序运行时，原来的数据被切成几分，分给不同的进程/线程执行，于是原先的次序被打破，用MPI或OpenMP的程序都有引入的这类潜在的结果差别。 其三，X87 FPU是以80位（1位符号，15位指数，64位数值）、扩展双精度浮点数运算的。SIMD执行单元可能不是（查遍手册，未见答案，至少其数据是以64位存放的）。 其四，四舍五入，(a) 1.0001 0000 1000 0011 1001 0111E2 101以单精度数表示时需要四舍五入，因为其数值有25位，超过单精度浮点数的24位。根据系统设置，有四种模式可选， -Round to nearest (even) --- 选精度误差最小的 -Round down (toward −∞) -- 选精度误差最小的, 但不大于原数 -Round up (toward +∞) --选精度误差最小的, 但不小于原数 -Round toward zero (Truncate) --选精度误差最小的, 但其绝对值不大于原数 其五，Flush-to-zero 和 denormal-to-zero. 如设定flush-to-zero, 当浮点运算发生underflow时，返回0值而不是像IEEE754要求的，返回非正规数据（denormalized data），这主要是为了提升性能。Denormal-to-zero是将非正规数据操作数置零，也是为性能。  其六，不良的编程习惯。如变量不置初值等 [...]]]></description>
			<content:encoded><![CDATA[<p>最近看到有开发HPC应用的程序员反映换了编译器后，新程序的结果不正确。我不禁想起20年前在16位IBM PC AT/XT台式机上开发CAD/CAM程序, 程序在计算边界状况时，如两圆柱的轴夹角为1分求交线，结果经常匪夷所思，都是精度惹得祸。进入64bit时代同样的问题仍然存在，单次运算的精度提高了，但HPC程序中的大量的迭代计算，累积了误差，导致结果不同。我读了Intel同事的文章（<a href="http://software.intel.com/en-us/articles/consistency-of-floating-point-results-using-the-intel-compiler">http://software.intel.com/en-us/articles/consistency-of-floating-point-results-using-the-intel-compiler</a>），略有所得，与大家分享。</p>
<p>人们要求结果的复现性有以下几方面，<br />
-同一程序，同一数据集，执行若干次的结果相同（近）<br />
-同一代码，不同编译选项产生的程序，相同的数据集，执行的结果相同（近）<br />
-同一代码，不同编译器产生的程序，相同的数据集，执行的结果相同（近）<br />
-同一代码，相同的数据集，在不同架构的CPU上执行的结果相同（近）<br />
最好运行速度也要快。这些要求有时是相互矛盾的。让我们先分析计算结果有差别的原因，注意这里我用了差别，而不是误差。</p>
<p>首先，通常十进制的浮点数用二进制数表示时就有误差，便有了‘原罪’。</p>
<p>其二，计算机运算是不符合结合律的，如A+B+C不一定等于A+(B+C)。当A= -B且C为极小值时，A+B+C=C，但A+(B+C)=0，极小值C和B相加时由于精度限制，被忽略了或者说表示B的有效位不能包含C的值；但A+B=0,再加C后，结果为C。当你多线程或多进程化程序运行时，原来的数据被切成几分，分给不同的进程/线程执行，于是原先的次序被打破，用MPI或OpenMP的程序都有引入的这类潜在的结果差别。</p>
<p>其三，X87 FPU是以80位（1位符号，15位指数，64位数值）、扩展双精度浮点数运算的。SIMD执行单元可能不是（查遍手册，未见答案，至少其数据是以64位存放的）。</p>
<p>其四，四舍五入，(<em>a</em>) 1.0001 0000 1000 0011 1001 0111E2 101以单精度数表示时需要四舍五入，因为其数值有25位，超过单精度浮点数的24位。根据系统设置，有四种模式可选，<br />
-Round to nearest (even) --- 选精度误差最小的<br />
-Round down (toward −∞) -- 选精度误差最小的, 但不大于原数<br />
-Round up (toward +∞) --选精度误差最小的, 但不小于原数<br />
-Round toward zero (Truncate) --选精度误差最小的, 但其绝对值不大于原数</p>
<p>其五，Flush-to-zero 和 denormal-to-zero. 如设定flush-to-zero, 当浮点运算发生underflow时，返回0值而不是像IEEE754要求的，返回非正规数据（denormalized data），这主要是为了提升性能。Denormal-to-zero是将非正规数据操作数置零，也是为性能。</p>
<p> 其六，不良的编程习惯。如变量不置初值等</p>
<p>我的同事将随后发如何巧用Intel编译器的选项避免结果差别，和如何发现导致结果差别的代码。</p>
]]></content:encoded>
			<wfw:commentRss>http://software.intel.com/zh-cn/blogs/2010/01/26/400003305/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>读针对AVX优化代码 --- 优化issue port的使用</title>
		<link>http://software.intel.com/zh-cn/blogs/2010/01/26/avx-issue-port/</link>
		<comments>http://software.intel.com/zh-cn/blogs/2010/01/26/avx-issue-port/#comments</comments>
		<pubDate>Tue, 26 Jan 2010 07:50:13 +0000</pubDate>
		<dc:creator>甘驰 (Intel)</dc:creator>
				<category><![CDATA[并行计算]]></category>
		<category><![CDATA[AVX]]></category>
		<category><![CDATA[issue port]]></category>

		<guid isPermaLink="false">http://software.intel.com/zh-cn/blogs/2010/01/26/avx-issue-port/</guid>
		<description><![CDATA[本文中的issue port专指CPU内部向其他执行单元(ALU, SSE MUL, DIV, Load, STD…)发送指令的通道，在Intel Micro Architectur(Sandy Bridge)中共有6个ports，port2,3,4负责存储单元，port0,1,5负责计算单元。若干计算单元会共享一个port，由于每个issue port只能同时向一个单元发送指令，故有时它们成为瓶颈，特别是port0,1,5。选择合适的指令来避免，如你的代码中大量用到shuffles指令，它们只能通过port5被发送，所以你要用vmovsldup ymm2, [mem]代替vmovsldup ymm2, ymm3来准备数据, 因为前者通过load port(2,3)发送，而后者通过port5。  Intel® 64 and IA-32 Architectures Optimization Reference Manual（248966）的54页列出了(Nehalem)issue port 和执行单元的对应关系。下表建立执行单元与port的关系 Executable operations Port Integer ALU 0,1,5 Integer Shift 0,5 Integer MUL 1 Integer LEA 1 Integer SIMD ALU 0,1,5 Integer SIMD Shift 1 Integer SIMD Shuffle 0,5 StringCompare [...]]]></description>
			<content:encoded><![CDATA[<p>本文中的issue port专指CPU内部向其他执行单元(ALU, SSE MUL, DIV, Load, STD…)发送指令的通道，在Intel Micro Architectur<strong>(Sandy Bridge)</strong>中共有6个ports，port2,3,4负责存储单元，port0,1,5负责计算单元。若干计算单元会共享一个port，由于每个issue port只能同时向一个单元发送指令，故有时它们成为瓶颈，特别是port0,1,5。选择合适的指令来避免，如你的代码中大量用到shuffles指令，它们只能通过port5被发送，所以你要用vmovsldup ymm2, [mem]代替vmovsldup ymm2, ymm3来准备数据, 因为前者通过load port(2,3)发送，而后者通过port5。</p>
<p> Intel® 64 and IA-32 Architectures Optimization Reference Manual（248966）的54页列出了<strong>(Nehalem)</strong><strong>i</strong>ssue port 和执行单元的对应关系。下表建立执行单元与port的关系</p>
<table border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td width="284" valign="top"><strong>Executable operations</strong></td>
<td width="131" valign="top"><strong>Port</strong></td>
</tr>
<tr>
<td width="284" valign="top">Integer ALU</td>
<td width="131" valign="top">0,1,5</td>
</tr>
<tr>
<td width="284" valign="top">Integer Shift</td>
<td width="131" valign="top">0,5</td>
</tr>
<tr>
<td width="284" valign="top">Integer MUL</td>
<td width="131" valign="top">1</td>
</tr>
<tr>
<td width="284" valign="top">Integer LEA</td>
<td width="131" valign="top">1</td>
</tr>
<tr>
<td width="284" valign="top">Integer SIMD ALU</td>
<td width="131" valign="top">0,1,5</td>
</tr>
<tr>
<td width="284" valign="top">Integer SIMD Shift</td>
<td width="131" valign="top">1</td>
</tr>
<tr>
<td width="284" valign="top">Integer SIMD Shuffle</td>
<td width="131" valign="top">0,5</td>
</tr>
<tr>
<td width="284" valign="top">StringCompare</td>
<td width="131" valign="top">1</td>
</tr>
<tr>
<td width="284" valign="top">FP ADD</td>
<td width="131" valign="top">1</td>
</tr>
<tr>
<td width="284" valign="top">(SP) FP MUL</td>
<td width="131" valign="top">0</td>
</tr>
<tr>
<td width="284" valign="top">(DP) FP MUL</td>
<td width="131" valign="top">0</td>
</tr>
<tr>
<td width="284" valign="top">FP MUL(X87)</td>
<td width="131" valign="top">0</td>
</tr>
<tr>
<td width="284" valign="top">FP/SIMD/SSE2 Move &amp; Logic</td>
<td width="131" valign="top">0,5</td>
</tr>
<tr>
<td width="284" valign="top">FP Shuffle</td>
<td width="131" valign="top">0</td>
</tr>
<tr>
<td width="284" valign="top">DIV/SQRT</td>
<td width="131" valign="top">0</td>
</tr>
<tr>
<td width="284" valign="top">JMP</td>
<td width="131" valign="top">5</td>
</tr>
</tbody>
</table>
<p>当你的程序大量使用那些只有一个issue port能发送的指令，要引起注意。当然Intel编译器会帮你优化，除非你直接写汇编。</p>
]]></content:encoded>
			<wfw:commentRss>http://software.intel.com/zh-cn/blogs/2010/01/26/avx-issue-port/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>读针对AVX优化代码 --- AVX/SSE切换</title>
		<link>http://software.intel.com/zh-cn/blogs/2010/01/11/avx-avxsse/</link>
		<comments>http://software.intel.com/zh-cn/blogs/2010/01/11/avx-avxsse/#comments</comments>
		<pubDate>Mon, 11 Jan 2010 03:02:22 +0000</pubDate>
		<dc:creator>甘驰 (Intel)</dc:creator>
				<category><![CDATA[其他]]></category>
		<category><![CDATA[英特尔® 软件网络 2.0]]></category>
		<category><![CDATA[AVX 编译器 AVX/SSE切换]]></category>

		<guid isPermaLink="false">http://software.intel.com/zh-cn/blogs/2010/01/11/avx-avxsse/</guid>
		<description><![CDATA[你可从http://www.intel.com/idf/technology-tracks/ -&#62; "32 nm Implementation of... " -&#62; "See sessions within this track" -&#62; ARCS002 PDF Icon 获得讲稿（PDF）。 AVX/SSE的切换话题在讲稿40页，和Intel® Advanced Vector Extensions Programming Reference（319433-006）的2-27页。 性能损失的原因：AVX和现有的SSE指令可混合使用，但SSE指令只使用YMM的低128位（XMM），这样就要求AVX和SSE依次访问某个YMM时，对其高128位予以保护，在AVX后执行的SSE指令要由硬件帮助报存该YMM的高128位，在执行下一AVX恢复。这就导致了性能损失，尤其在循环内。 解决方法： 1。避免切换。只用VEX前缀的128bit和256bit指令(128bit或256bit的AVX)或只用SSE指令。 2。 将SSE指令转成128bit的AVX指令。英特尔编译器11.1版加/QaAVX选项后会将inline的汇编代码中SSE转成128bit的AVX指令。 3。 执行AVX后的SSE前，插入VZEROUPPER指令，它将所有YMM的高128位清零。VZEROALL则将所有YMM的256位清零。例如，在256bit的AVS代码调用包含传统SSE指令的库函数前，先执行VZEROUPPER避免延时。 在Pentium时代，浮点数转换成整形很耗时，且在一些不严谨的程序员的代码中比比皆是，最后Intel Compiler产生的新instruction(FIST/FISTP)帮助大家一劳永逸地，不知不觉地解决了。 总之，AVX/SSE切换影响面广，但解决方法却是简单的，用Intel Compiler V11.1重编译一次。]]></description>
			<content:encoded><![CDATA[<p>你可从<a href="http://www.intel.com/idf/technology-tracks/">http://www.intel.com/idf/technology-tracks/</a> -&gt; "32 nm Implementation of... " -&gt; "See sessions within this track" -&gt; ARCS002 PDF Icon 获得讲稿（PDF）。 AVX/SSE的切换话题在讲稿40页，和Intel® Advanced Vector Extensions Programming Reference（319433-006）的2-27页。</p>
<p><strong>性能损失的原因</strong>：AVX和现有的SSE指令可混合使用，但SSE指令只使用YMM的低128位（XMM），这样就要求AVX和SSE依次访问某个YMM时，对其高128位予以保护，在AVX后执行的SSE指令要由硬件帮助报存该YMM的高128位，在执行下一AVX恢复。这就导致了性能损失，尤其在循环内。</p>
<p><strong>解决方法：</strong></p>
<p>1。避免切换。只用VEX前缀的128bit和256bit指令(128bit或256bit的AVX)或只用SSE指令。</p>
<p>2。 将SSE指令转成128bit的AVX指令。英特尔编译器11.1版加/QaAVX选项后会将inline的汇编代码中SSE转成128bit的AVX指令。</p>
<p>3。 执行AVX后的SSE前，插入VZEROUPPER指令，它将所有YMM的高128位清零。VZEROALL则将所有YMM的256位清零。例如，在256bit的AVS代码调用包含传统SSE指令的库函数前，先执行VZEROUPPER避免延时。</p>
<p>在Pentium时代，浮点数转换成整形很耗时，且在一些不严谨的程序员的代码中比比皆是，最后Intel Compiler产生的新instruction(FIST/FISTP)帮助大家一劳永逸地，不知不觉地解决了。</p>
<p>总之，AVX/SSE切换影响面广，但解决方法却是简单的，用Intel Compiler V11.1重编译一次。</p>
]]></content:encoded>
			<wfw:commentRss>http://software.intel.com/zh-cn/blogs/2010/01/11/avx-avxsse/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>读AVX编程参考的一点所得</title>
		<link>http://software.intel.com/zh-cn/blogs/2009/12/29/avx/</link>
		<comments>http://software.intel.com/zh-cn/blogs/2009/12/29/avx/#comments</comments>
		<pubDate>Tue, 29 Dec 2009 05:09:08 +0000</pubDate>
		<dc:creator>甘驰 (Intel)</dc:creator>
				<category><![CDATA[并行计算]]></category>
		<category><![CDATA[英特尔® 软件网络 2.0]]></category>
		<category><![CDATA[AVX]]></category>
		<category><![CDATA[编译器]]></category>

		<guid isPermaLink="false">http://software.intel.com/zh-cn/blogs/2009/12/29/avx/</guid>
		<description><![CDATA[AVX(Advanced Vector Extensions)是下一代Intel CPU中一个重要的新技术，抽空看了一点，记一些笔记。  增加了256-bit的SIMD寄存器，YMM0~YMM15, 其中低128-bit即 以前的XMM。  新增了FMA(fused-multiply-add)等指令以加强浮点运算能力, 如VFMADD132PD ymm0, ymm1, ymm2/256将ymm0和ymm2/mem中双精度浮点数相乘和ymm1相加并存入ymm0中。两步并一步。该指令有相应的Intrinsic VFMADD132PD_m256d_mm234_fmadd_pd(_m256d a, _m256d b, _m256d c);  Intel Compiler V11.1已支持AVX指令集。  新增了PCLMULQDQ等指令以加强对AES(Advanced Encryption Standard)算法支持，如PCLMULQDQ xmm1, xmm2/m128, imm8将xmm1的高或低64bit乘xmm2的高或低64bit并存回xmm1, imm8决定xmm1和xmm2的高低64bit。  内存对齐，一个老话题。前几代CPU的性能或多或少得受它影响，AVX中 以VEX前缀编码的算术指令和内存访问指令在访问内存时更灵活，即可访问对齐的或未对齐数据，当然访问未对齐数据，会有惩罚(penalty)，具体多少参考未说，想必要小。 在Core i7访问跨行未对齐的数据的惩罚为4～5cycles，不跨行的为2cycles。  顺便提一下，Nehalem的store-forwarding对数据对齐的要求也宽松了许多，起始地址不是数据长度整数倍的数据也可被forward了。  ---呼吁--- 若干SSE4.2和AVX的指令功能复杂，本身是针对某种特定运算模式（pattern）设计的，很难由编译器通过分析若干行高级语言代码后直接生成，故在很大程度上依靠一些资深软件工程师直接编写汇编。我想大家不妨将自己编写的，使用这些指令完成特定功能的代码封装成函数，上传共享以方便更多的人。  例如在 http://softwarecommunity.intel.com/isn/downloads/intelavx/AES-Instructions-Set_WP.pdf 详细介绍了AVX中Advanced Encryption Standard (AES) Instructions Set，并附上例子代码。  我在CSDN开专门的新帖http://topic.csdn.net/u/20091229/11/bb9065f7-d523-451a-9424-4a19dfb8c378.html ，欢迎上传。]]></description>
			<content:encoded><![CDATA[<p>AVX(Advanced Vector Extensions)是下一代Intel CPU中一个重要的新技术，抽空看了一点，记一些笔记。</p>
<p> 增加了256-bit的SIMD寄存器，YMM0~YMM15, 其中低128-bit即 以前的XMM。</p>
<p> 新增了FMA(fused-multiply-add)等指令以加强浮点运算能力, 如<em>VFMADD132PD ymm0, ymm1, ymm2/256</em>将ymm0和ymm2/mem中双精度浮点数相乘和ymm1相加并存入ymm0中。两步并一步。该指令有相应的Intrinsic VFMADD132PD_m256d_mm234_fmadd_pd(_m256d a, _m256d b, _m256d c);  Intel Compiler V11.1已支持AVX指令集。</p>
<p> 新增了PCLMULQDQ等指令以加强对AES(Advanced Encryption Standard)算法支持，如<em>PCLMULQDQ xmm1, xmm2/m128, imm8</em>将xmm1的高或低64bit乘xmm2的高或低64bit并存回xmm1, imm8决定xmm1和xmm2的高低64bit。</p>
<p> 内存对齐，一个老话题。前几代CPU的性能或多或少得受它影响，AVX中 以VEX前缀编码的算术指令和内存访问指令在访问内存时更灵活，即可访问对齐的或未对齐数据，当然访问未对齐数据，会有惩罚(penalty)，具体多少参考未说，想必要小。 在Core i7访问跨行未对齐的数据的惩罚为4～5cycles，不跨行的为2cycles。</p>
<p> 顺便提一下，Nehalem的store-forwarding对数据对齐的要求也宽松了许多，起始地址不是数据长度整数倍的数据也可被forward了。</p>
<p> <strong>---</strong><strong>呼吁</strong><strong>---</strong></p>
<p>若干SSE4.2和AVX的指令功能复杂，本身是针对某种特定运算模式（pattern）设计的，很难由编译器通过分析若干行高级语言代码后直接生成，故在很大程度上依靠一些资深软件工程师直接编写汇编。我想大家不妨将自己编写的，使用这些指令完成特定功能的代码封装成函数，上传共享以方便更多的人。</p>
<p> 例如在 <a href="http://softwarecommunity.intel.com/isn/downloads/intelavx/AES-Instructions-Set_WP.pdf">http://softwarecommunity.intel.com/isn/downloads/intelavx/AES-Instructions-Set_WP.pdf</a> 详细介绍了AVX中Advanced Encryption Standard (AES) Instructions Set，并附上例子代码。</p>
<p> 我在CSDN开专门的新帖<a href="http://topic.csdn.net/u/20091229/11/bb9065f7-d523-451a-9424-4a19dfb8c378.html">http://topic.csdn.net/u/20091229/11/bb9065f7-d523-451a-9424-4a19dfb8c378.html</a> ，欢迎上传。</p>
]]></content:encoded>
			<wfw:commentRss>http://software.intel.com/zh-cn/blogs/2009/12/29/avx/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Parallel Advisor怎么工作的？</title>
		<link>http://software.intel.com/zh-cn/blogs/2009/11/23/parallel-advisor-2/</link>
		<comments>http://software.intel.com/zh-cn/blogs/2009/11/23/parallel-advisor-2/#comments</comments>
		<pubDate>Mon, 23 Nov 2009 07:26:23 +0000</pubDate>
		<dc:creator>甘驰 (Intel)</dc:creator>
				<category><![CDATA[博客征文专栏]]></category>
		<category><![CDATA[英特尔® 软件网络 2.0]]></category>
		<category><![CDATA[Intel Parallel Advisor Lite]]></category>

		<guid isPermaLink="false">http://software.intel.com/zh-cn/blogs/2009/11/23/parallel-advisor-2/</guid>
		<description><![CDATA[一段源代码， for (int p = 3; p &#60;= limit; p += 2) { if (IsPrime(p)) Tick(); } 用户需手工标注ANNOTATE_*，Parallel Advisor认为代码将并行执行。 ANNOTATE_SITE_BEGIN for (int p = 3; p &#60;= limit; p += 2) { ANNOTATE_TASK_BEGIN if (IsPrime(p)) Tick(); ANNOTATE_TASK_END } ANNOTATE_SITE_END Parallel Advisor识别的标识（ANNOTATE_*）是一个宏， 如 #define ANNOTATE_SITE_BEGIN { _ANNOTATE_CALL_0(BeginConcurrencySite) { #define ANNOTATE_SITE_END } _ANNOTATE_CALL_0(EndConcurrencySite) } 编译后，Parallel Advisor启动该程序，这些宏(函数)便调用Parallel Advisor的库，记录相关信息。标识分四类 [...]]]></description>
			<content:encoded><![CDATA[<p>一段源代码，<br />
for (int p = 3; p &lt;= limit; p += 2) {<br />
if (IsPrime(p)) Tick();<br />
}<br />
用户需手工标注ANNOTATE_*，Parallel Advisor认为代码将并行执行。<br />
ANNOTATE_SITE_BEGIN<br />
for (int p = 3; p &lt;= limit; p += 2) {<br />
ANNOTATE_TASK_BEGIN<br />
if (IsPrime(p)) Tick();<br />
ANNOTATE_TASK_END<br />
}<br />
ANNOTATE_SITE_END</p>
<p>Parallel Advisor识别的标识（ANNOTATE_*）是一个宏， 如<br />
#define ANNOTATE_SITE_BEGIN { _ANNOTATE_CALL_0(BeginConcurrencySite) {<br />
#define ANNOTATE_SITE_END } _ANNOTATE_CALL_0(EndConcurrencySite) }<br />
编译后，Parallel Advisor启动该程序，这些宏(函数)便调用Parallel Advisor的库，记录相关信息。标识分四类<br />
 ANNOTATE_SITE_*: 说明一个并行点的静态范围（代码段）<br />
 ANNOTATE_TASK_*: 说明一个将并行的任务的静态范围（代码段），一个ANNOTATE_SITE中可有若干个ANNOTATE_TASK.<br />
 ANNOTATE_LOCK*： 说明一个同步点。<br />
 ANNOTATE_MEMORY_*： 说明一个用户自定义的，非标准库提供的内存操， 如非malloc/free和new/delete。 你应该把ANNOTATE_MEMORY_ALLOCATION(ptr,size)写在自定义的内存分配函数之前，把ANNOTATE_MEMORY_DEALLOCATION(ptr)写在自定义的内存释放函数之前，以帮助Parallel Advisor分析data race.</p>
<p>ANNOTATE_LOCK中的ANNOTATE_LOCKID_ACQUIRE(int)/ANNOTATE_LOCKID_RELEASE(int)和ANOOTATE_CRITICAL_BEGIN(int)/ANNOTATE_CRITICAL_END功能相近，不同在于ANNOTATE_LOCKID_*在获取和释放时都需以唯一的LOCKID，而ANNOTATE_CRITICAL_*在释放时不需要LOCKID。ANNOTATE_CRITITICAL_*用带有的destructor的C++类实现，即使从exception退出，LOCKID也会被正确释放。</p>
<p>关于嵌套任务的执行原则是在子任务被创建前的父任务中的代码会在子任务之前被执行，之后的代码则可能与子任务(嵌套任务)并行执行。<br />
ANNOTATE_SITE_BEGIN<br />
for (i=0; i&lt;N; i++) {<br />
ANNOTATE_TASK_BEGIN<br />
func1a(i);<br />
ANNOTATE_TASK_BEGIN<br />
func2(i);<br />
ANNOTATE_TASK_END<br />
func1b(i);<br />
ANNOTATE_TASK_END<br />
}<br />
ANNOTATE_SITE_END<br />
例子中的func1a(i)不会与func2(i)或func1b(i)被并行执行，func2(i)和func1(i)会被并行。这里讨论的只是在同一个循环迭代中（loop iteration），在不同的循环迭代中, 如func1a(2)仍可能和func2(4)并行执行。</p>
]]></content:encoded>
			<wfw:commentRss>http://software.intel.com/zh-cn/blogs/2009/11/23/parallel-advisor-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Parallel Advisor能干啥？</title>
		<link>http://software.intel.com/zh-cn/blogs/2009/11/02/parallel-advisor/</link>
		<comments>http://software.intel.com/zh-cn/blogs/2009/11/02/parallel-advisor/#comments</comments>
		<pubDate>Mon, 02 Nov 2009 07:28:49 +0000</pubDate>
		<dc:creator>甘驰 (Intel)</dc:creator>
				<category><![CDATA[其他]]></category>
		<category><![CDATA[并行计算]]></category>
		<category><![CDATA[英特尔® 软件网络 2.0]]></category>
		<category><![CDATA[Parallel Advisor]]></category>

		<guid isPermaLink="false">http://software.intel.com/zh-cn/blogs/2009/11/02/parallel-advisor/</guid>
		<description><![CDATA[顾名思义，给你一些编写并行程序的指导。它是Intel Parallel Studio套件中的四大组件之一，帮助编程者将现有的单线程程序改成多线程。 面对几年前开发的数十万、上百万行代码，即使是原设计师也会觉得棘手，从何处着手加入并行代码？可能会造成什么错误？完成后性能提高多少？一系列问题可能会阻挠你做正确的事，但Parallel Advisor将帮你在动手改代码前，得到这些问题的答案。 图示了Parallel Advisor的工作流程。首先，它分析该程序的运行，发现程序的热点，即耗时较多的部分。这时我们需要进一步分析该段代码，确定并行区域和任务。并行区域一般是一个循环体，任务是指将循环体内代码和数据被细分，未来被分配给多个线程同时运行的。这时我们并不需要直接改代码，而是以一种Parallel Advisor能识别的方法将并行区域和任务标识出来。 其次，Parallel Advisor运行和分析新代码，找到数据竞争访问（Data Race）的错误。同样我们也无需改动代码，只需标识对该数据进行保护。我们需要重复此步骤若干次，直至无错。 最后，将那些Parallel Advisor能识别的标识，用各种线程实现的方法逐个替换。 强调一下，前两步时无需改写代码。具体如何实现的，下次再讲。]]></description>
			<content:encoded><![CDATA[<p><a href="http://software.intel.com/zh-cn/blogs/wordpress/wp-content/uploads/2009/11/advisor-1.jpg"><img class="alignleft size-full wp-image-400002628" src="http://software.intel.com/zh-cn/blogs/wordpress/wp-content/uploads/2009/11/advisor-1.jpg" alt="" width="500" height="323" /></a>顾名思义，给你一些编写并行程序的指导。它是Intel Parallel Studio套件中的四大组件之一，帮助编程者将现有的单线程程序改成多线程。<br />
面对几年前开发的数十万、上百万行代码，即使是原设计师也会觉得棘手，从何处着手加入并行代码？可能会造成什么错误？完成后性能提高多少？一系列问题可能会阻挠你做正确的事，但Parallel Advisor将帮你在动手改代码前，得到这些问题的答案。</p>
<p>图示了Parallel Advisor的工作流程。首先，它分析该程序的运行，发现程序的热点，即耗时较多的部分。这时我们需要进一步分析该段代码，确定并行区域和任务。并行区域一般是一个循环体，任务是指将循环体内代码和数据被细分，未来被分配给多个线程同时运行的。这时我们并不需要直接改代码，而是以一种Parallel Advisor能识别的方法将并行区域和任务标识出来。<br />
其次，Parallel Advisor运行和分析新代码，找到数据竞争访问（Data Race）的错误。同样我们也无需改动代码，只需标识对该数据进行保护。我们需要重复此步骤若干次，直至无错。<br />
最后，将那些Parallel Advisor能识别的标识，用各种线程实现的方法逐个替换。</p>
<p>强调一下，前两步时无需改写代码。具体如何实现的，下次再讲。</p>
]]></content:encoded>
			<wfw:commentRss>http://software.intel.com/zh-cn/blogs/2009/11/02/parallel-advisor/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

