<?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; gengshenghong</title>
	<atom:link href="http://software.intel.com/zh-cn/blogs/author/gengshenghong/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>Win32 多线程的创建方法和基本使用</title>
		<link>http://software.intel.com/zh-cn/blogs/2011/12/02/win32/</link>
		<comments>http://software.intel.com/zh-cn/blogs/2011/12/02/win32/#comments</comments>
		<pubDate>Fri, 02 Dec 2011 09:17:21 +0000</pubDate>
		<dc:creator>gengshenghong</dc:creator>
				<category><![CDATA[博客征文专栏]]></category>
		<category><![CDATA[并行计算]]></category>

		<guid isPermaLink="false">http://software.intel.com/zh-cn/blogs/2011/12/02/win32/</guid>
		<description><![CDATA[Summary： 总结Win32提供的创建多线程相关的API接口和基本的使用框架。 Ref: MSDN: http://msdn.microsoft.com/zh-cn/library/y6h8hye8(v=VS.100) Win32多线程的创建方法主要有： （1）CreateThread() （2）_beginthread()&#38;&#38;_beginthreadex() （3）AfxBeginThread() （4）CWinThread类 （1）CreateThread() 百度百科：http://baike.baidu.com/view/1191444.htm 函数原型： view plaincopy to clipboardprint? 01.HANDLE CreateThread( 02.　　LPSECURITY_ATTRIBUTES lpThreadAttributes, 03.　　DWORD dwStackSize, 04.　　LPTHREAD_START_ROUTINE lpStartAddress, 05.　　LPVOID lpParameter, 06.　　DWORD dwCreationFlags, 07.　　LPDWORD lpThreadId); 08.} HANDLE CreateThread( 　　LPSECURITY_ATTRIBUTES lpThreadAttributes, 　　DWORD dwStackSize, 　　LPTHREAD_START_ROUTINE lpStartAddress, 　　LPVOID lpParameter, 　　DWORD dwCreationFlags, 　　LPDWORD lpThreadId); } 头文件：Windows.h CreateThread是Win32提供的创建线程的最基础的API，用于在主线程上创建一个线程。返回一个HANDLE句柄（内核对象）。 参数简要说明： lpThreadAttributes：线程属性，用于设置线程的属性，NULL表示使用默认的设置。dwStackSize：线程堆栈大小，使用0采用默认设置，windows会根据需要动态增加堆栈大小。lpStartAddress：指向线程函数的指针。lpParameter：向线程函数传递的参数。dwCreationFlags：线程标志，CREATE_SUSPENDED表示创建一个挂起的线程，0表示创建后立即激活线程。lpThreadId，先线程的ID（输出参数）。 创建线程的代码： view plaincopy to [...]]]></description>
			<content:encoded><![CDATA[<p>Summary：</p>
<p>总结Win32提供的创建多线程相关的API接口和基本的使用框架。</p>
<p>Ref:</p>
<p>MSDN: http://msdn.microsoft.com/zh-cn/library/y6h8hye8(v=VS.100)</p>
<p>Win32多线程的创建方法主要有：</p>
<p>（1）CreateThread()</p>
<p>（2）_beginthread()&amp;&amp;_beginthreadex()</p>
<p>（3）AfxBeginThread()</p>
<p>（4）CWinThread类</p>
<p>（1）CreateThread()</p>
<p>百度百科：http://baike.baidu.com/view/1191444.htm</p>
<p>函数原型：</p>
<p>view plaincopy to clipboardprint?<br />
01.HANDLE CreateThread(<br />
02.　　LPSECURITY_ATTRIBUTES lpThreadAttributes,<br />
03.　　DWORD dwStackSize,<br />
04.　　LPTHREAD_START_ROUTINE lpStartAddress,<br />
05.　　LPVOID lpParameter,<br />
06.　　DWORD dwCreationFlags,<br />
07.　　LPDWORD lpThreadId);<br />
08.}<br />
HANDLE CreateThread(<br />
　　LPSECURITY_ATTRIBUTES lpThreadAttributes,<br />
　　DWORD dwStackSize,<br />
　　LPTHREAD_START_ROUTINE lpStartAddress,<br />
　　LPVOID lpParameter,<br />
　　DWORD dwCreationFlags,<br />
　　LPDWORD lpThreadId);<br />
}</p>
<p>头文件：Windows.h</p>
<p>CreateThread是Win32提供的创建线程的最基础的API，用于在主线程上创建一个线程。返回一个HANDLE句柄（内核对象）。</p>
<p>参数简要说明：</p>
<p>lpThreadAttributes：线程属性，用于设置线程的属性，NULL表示使用默认的设置。dwStackSize：线程堆栈大小，使用0采用默认设置，windows会根据需要动态增加堆栈大小。lpStartAddress：指向线程函数的指针。lpParameter：向线程函数传递的参数。dwCreationFlags：线程标志，CREATE_SUSPENDED表示创建一个挂起的线程，0表示创建后立即激活线程。lpThreadId，先线程的ID（输出参数）。</p>
<p>创建线程的代码：</p>
<p>view plaincopy to clipboardprint?<br />
01.#include "stdafx.h"<br />
02.#include<br />
03.<br />
04.DWORD WINAPI ThreadProc(LPVOID lpParam)<br />
05.{<br />
06. printf("sub thread started\n");<br />
07. printf("sub thread finished\n");<br />
08. return 0;<br />
09.}<br />
10.<br />
11.int main(int argc, char* argv[])<br />
12.{<br />
13. DWORD threadID;<br />
14. HANDLE hThread;<br />
15. hThread = CreateThread(NULL,0,ThreadProc,NULL,0,&amp;threadID); // 创建线程<br />
16.<br />
17. return 0;<br />
18.}<br />
#include "stdafx.h"<br />
#include</p>
<p>DWORD WINAPI ThreadProc(LPVOID lpParam)<br />
{<br />
printf("sub thread started\n");<br />
printf("sub thread finished\n");<br />
return 0;<br />
}</p>
<p>int main(int argc, char* argv[])<br />
{<br />
DWORD threadID;<br />
HANDLE hThread;<br />
hThread = CreateThread(NULL,0,ThreadProc,NULL,0,&amp;threadID); // 创建线程</p>
<p>return 0;<br />
}<br />
如果直接使用上面的代码，那么很可能没有任何输出，这是由于主线程创建了子线程后主线程继续向下运行，子线程还没来得及执行里面的代码主线程可能就结束了。这就需要另一个API来进行同步：WaitForSingleObject()。</p>
<p>与之对应的还有WaitForMultipleObjects，用于同步一组内核对象。（参考http://msdn.microsoft.com/zh-cn/site/ms686360获取所有的同步函数（Synchronization Functions）的使用。</p>
<p>WaitForSingleObject原型：DWORD WINAPI WaitForSingleObject(__in HANDLE hHandle, __in DWORD dwMilliseconds);其中，第一个参数是要等待的内核对象的句柄，第二个参数是设置等待超时时间，可以设置为INFINITE，表示一直等待直到有信号触发。</p>
<p>在内核对象使用完毕后，一般需要关闭，使用CloseHandle()函数，参数为内核对象句柄。</p>
<p>所以，以下是一个最基本的使用CreateThread的例子：</p>
<p>view plaincopy to clipboardprint?<br />
01.#include "stdafx.h"<br />
02.#include<br />
03.<br />
04.DWORD WINAPI ThreadProc(LPVOID lpParam)<br />
05.{<br />
06. printf("sub thread started\n");<br />
07. // TODO: Add your thread code here.<br />
08. printf("sub thread finished\n");<br />
09. return 0;<br />
10.}<br />
11.<br />
12.int main(int argc, char* argv[])<br />
13.{<br />
14. DWORD threadID;<br />
15. HANDLE hThread;<br />
16. hThread = CreateThread(NULL,0,ThreadProc,NULL,0,&amp;threadID); // 创建线程<br />
17.<br />
18. WaitForSingleObject(hThread,INFINITE);<br />
19. CloseHandle(hThread); // 关闭内核对象<br />
20.<br />
21. return 0;<br />
22.}<br />
#include "stdafx.h"<br />
#include</p>
<p>DWORD WINAPI ThreadProc(LPVOID lpParam)<br />
{<br />
printf("sub thread started\n");<br />
// TODO: Add your thread code here.<br />
printf("sub thread finished\n");<br />
return 0;<br />
}</p>
<p>int main(int argc, char* argv[])<br />
{<br />
DWORD threadID;<br />
HANDLE hThread;<br />
hThread = CreateThread(NULL,0,ThreadProc,NULL,0,&amp;threadID); // 创建线程</p>
<p>WaitForSingleObject(hThread,INFINITE);<br />
CloseHandle(hThread); // 关闭内核对象</p>
<p>return 0;<br />
}<br />
（2）_beginthread()&amp;&amp;_beginthreadex()</p>
<p>百度百科：http://baike.baidu.com/view/3029167.htm</p>
<p>MSDN：http://msdn.microsoft.com/zh-cn/library/kdzttdcb.aspx</p>
<p>函数原型：</p>
<p>view plaincopy to clipboardprint?<br />
01.uintptr_t _beginthread( // NATIVE CODE<br />
02. void( __cdecl *start_address )( void * ),<br />
03. unsigned stack_size,<br />
04. void *arglist<br />
05.);<br />
uintptr_t _beginthread( // NATIVE CODE<br />
void( __cdecl *start_address )( void * ),<br />
unsigned stack_size,<br />
void *arglist<br />
);</p>
<p>头文件：process.h</p>
<p>参数说明：第一个参数是线程函数的指针，第二个参数是堆栈大小，第三个参数是要传递给线程函数的参数列表。返回值也是线程句柄（关于更多说明，参考MSDN)。<br />
同样，对于_beginthread()的同步，和CreateThread一样可以使用WaitForSingleObject函数，CloseHandle()关闭内核对象。另外，_beginthread()的线程函数是无返回值类型的，可以使用_endthread()在线程函数中结束线程。</p>
<p>下面是一个使用_beginthread()的基本的例子：</p>
<p>view plaincopy to clipboardprint?<br />
01.#include "stdafx.h"<br />
02.#include<br />
03.#include<br />
04.<br />
05.void __cdecl ThreadProc(void *para)<br />
06.{<br />
07. printf("sub thread started\n");<br />
08. // TODO: Add your thread code here.<br />
09. printf("sub thread finished\n");<br />
10. _endthread(); // 可以省略，隐含会调用。<br />
11.}<br />
12.<br />
13.int main(int argc, char* argv[])<br />
14.{<br />
15. HANDLE hThread = (HANDLE)_beginthread(ThreadProc, 0, NULL);<br />
16.<br />
17. WaitForSingleObject(hThread,INFINITE);<br />
18. CloseHandle(hThread);<br />
19.}<br />
#include "stdafx.h"<br />
#include<br />
#include</p>
<p>void __cdecl ThreadProc(void *para)<br />
{<br />
printf("sub thread started\n");<br />
// TODO: Add your thread code here.<br />
printf("sub thread finished\n");<br />
_endthread(); // 可以省略，隐含会调用。<br />
}</p>
<p>int main(int argc, char* argv[])<br />
{<br />
HANDLE hThread = (HANDLE)_beginthread(ThreadProc, 0, NULL);</p>
<p>WaitForSingleObject(hThread,INFINITE);<br />
CloseHandle(hThread);<br />
}另外，还有一个函数_beginthreadex()，可以简单的认为_beginthread()为其简化版，所以更多的时候是使用更简单的_beginthread()了。<br />
说明：在MSDN中可以看到一句很重要的提示，内容为“For an executable file linked with Libcmt.lib, do not call the Win32 ExitThread API; this prevents the run-time system from reclaiming allocated resources. _endthread and _endthreadex reclaim allocated thread resources and then call ExitThread.”，简单翻译就是说，对于链接Libcmt.lib的可执行程序，不要使用Win32的线程退出函数(ExitThread)，这会阻止运行时系统回收分配的资源，应该使用_endthread，它能回收分配的线程资源然后调用ExitThread。这个问题看似没有提到CreateThread()，但是其实有关，这就是经常看到有些资料上坚决的说到”不要使用CreateThread创建线程，否则会内存泄漏“的来源了。</p>
<p>问题引出：CreateThread的内存泄漏问题（CreateThread和_beginthread的区别）</p>
<p>Related Topics：http://wenku.baidu.com/view/adede4ec4afe04a1b071dea4.html http://www.cnblogs.com/whiteyun/archive/2011/06/02/2067742.html ....</p>
<p>1. _beginthread也是通过CreateThread来创建线程的，只是_beginthread对其进行了一些封装，将相关”资源“通过线程的本地存储（TLS）传递给了线程函数的参数，然后在调用_endthread的时候，会将这些保存的资源进行释放。</p>
<p>2. 并不是所有的使用CreateThread的情况都会有内存泄漏。看了很多人的文章，只有http://wenku.baidu.com/view/adede4ec4afe04a1b071dea4.html的分析是最清晰的，我已经转到http://dl.dbank.com/c03ljl2iud了，可下载查看（版权归原作者所有）。</p>
<p>总之，建议是使用_beginthread取代CreateThread来创建线程。</p>
<p>（3）AfxBeginThread()：</p>
<p>很显然，这是MFC中的Afx系列函数，一个在MFC中创建线程的全局函数。由于现在也不怎么用MFC了，这里就不多说了。</p>
<p>（4）CWinThread类：</p>
<p>很显然，是MFC中创建线程的类，同上，不多说了。</p>
<p>欢迎补充！</p>
<p>（1）补充内容：</p>
<p>关于WaitForMultipleObjects在_beginthread无法使用的问题</p>
<p>问题：使用_beginthread创建多个线程，无法使用WaitForMultipleObjects来进行同步。</p>
<p>这个问题可以用下面的例子来测试：</p>
<p>view plaincopy to clipboardprint?<br />
01.#include "stdafx.h"<br />
02.#include<br />
03.#include<br />
04.<br />
05.void __cdecl ThreadProc(void *para)<br />
06.{<br />
07. printf("sub thread started\n");<br />
08. // TODO: Add your thread code here.<br />
09. printf("sub thread finished\n");<br />
10. _endthread(); // 可以省略，隐含会调用。<br />
11.}<br />
12.<br />
13.int main(int argc, char* argv[])<br />
14.{<br />
15. DWORD threadID;<br />
16. HANDLE hThread[10];<br />
17. for(int i =0;i&lt;10;i++)<br />
18. hThread[i] = (HANDLE)_beginthread(ThreadProc,0,NULL);<br />
19.<br />
20. WaitForMultipleObjects(10, hThread,TRUE,INFINITE); //无法同步所有线程！<br />
21. for(int i = 0;i&lt;10;i++) {<br />
22. CloseHandle(hThread);<br />
23. }<br />
24.}<br />
#include "stdafx.h"<br />
#include<br />
#include</p>
<p>void __cdecl ThreadProc(void *para)<br />
{<br />
printf("sub thread started\n");<br />
// TODO: Add your thread code here.<br />
printf("sub thread finished\n");<br />
_endthread(); // 可以省略，隐含会调用。<br />
}</p>
<p>int main(int argc, char* argv[])<br />
{<br />
DWORD threadID;<br />
HANDLE hThread[10];<br />
for(int i =0;i&lt;10;i++)<br />
hThread[i] = (HANDLE)_beginthread(ThreadProc,0,NULL);</p>
<p>WaitForMultipleObjects(10, hThread,TRUE,INFINITE); //无法同步所有线程！<br />
for(int i = 0;i&lt;10;i++) {<br />
CloseHandle(hThread);<br />
}<br />
}<br />
期望的结果是程序能输出10次的线程创建结束的消息，但是实际运行发现，无法达到这么多次数。为何？这是因为WaitForMultipleObjects在这里无法正常工作。原因是：</p>
<p>_endthread()在结束线程的时候，会自动调用CloseHandle关闭内核对象。这就容易解释了，如果提前关闭了内核对象，WaitForMultipleObjects会返回错误。那么有没有专门用于_beginthread创建的线程的同步方法呢，就我目前所知，好象是没有的！要解决这里的问题，可以分别调用WaitForSingleObject来同步，当然，使用其他一些变相的方法也是可以的，另外，上面的CloseHandle当然就可以不用再调用了。</p>
<p>总结：看来_beginthread也不是那么好用。:）</p>
]]></content:encoded>
			<wfw:commentRss>http://software.intel.com/zh-cn/blogs/2011/12/02/win32/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>高性能计算中并行的概念理解</title>
		<link>http://software.intel.com/zh-cn/blogs/2011/12/02/400009299/</link>
		<comments>http://software.intel.com/zh-cn/blogs/2011/12/02/400009299/#comments</comments>
		<pubDate>Fri, 02 Dec 2011 09:14:47 +0000</pubDate>
		<dc:creator>gengshenghong</dc:creator>
				<category><![CDATA[博客征文专栏]]></category>
		<category><![CDATA[并行计算]]></category>
		<category><![CDATA[服务器]]></category>

		<guid isPermaLink="false">http://software.intel.com/zh-cn/blogs/2011/12/02/400009299/</guid>
		<description><![CDATA[  要理解并行编程，首先要从并行的理解开始。 （1）从Wiki中并行编程的解释说起 Wiki是个好东西，包含了很多专业术语的解释，关键的是，除了解释，wiki还是一个好文档。 Paralle Programming（并行编程/并行计算）Wiki：http://en.wikipedia.org/wiki/Parallel_programming Parallel computing is a form of computation in which many calculations are carried out simultaneously,[1] operating on the principle that large problems can often be divided into smaller ones, which are then solved concurrently ("in parallel"). There are several different forms of parallel computing: bit-level, instruction level, data, and [...]]]></description>
			<content:encoded><![CDATA[<p> </p>
<p>要理解并行编程，首先要从并行的理解开始。</p>
<p>（1）从Wiki中并行编程的解释说起</p>
<p>Wiki是个好东西，包含了很多专业术语的解释，关键的是，除了解释，wiki还是一个好文档。</p>
<p>Paralle Programming（并行编程/并行计算）Wiki：<a href="http://en.wikipedia.org/wiki/Parallel_programming">http://en.wikipedia.org/wiki/Parallel_programming</a><br />
Parallel computing is a form of computation in which many calculations are carried out simultaneously,[1] operating on the principle that large problems can often be divided into smaller ones, which are then solved concurrently ("in parallel"). There are several different forms of parallel computing: bit-level, instruction level, data, and task parallelism. Parallelism has been employed for many years, mainly in high-performance computing.</p>
<p>这里要讨论的就是上面的这句话中加粗的部分的内容。要理解好并行编程，首先需要理解并行编程的形式。并行编程的形式包括：</p>
<p>bit-level parallelism：位级别的并行，是基于处理器的字长不断增加的基础上，就比较容易理解了。处理器的字长不断增加，并行度自然增加。（<a href="http://en.wikipedia.org/wiki/Bit-level_parallelism">http://en.wikipedia.org/wiki/Bit-level_parallelism</a>）</p>
<p>instruction level parallelism（ILP）：指令级并行，是指处理器能同时处理多条指令。</p>
<p>data level parallelism（DLP）：数据集并行，是指处理器能同时处理多条数据。</p>
<p>task level parallelism（TLP）：任务级并行，我见过更多的是称为Thread-level parallelism（TLP），即线程级并行。</p>
<p>下面就这些并行的概念进行进一步分析，这些并行的方式，特别是BLP、ILP和DLP本身都是和处理器微架构有关的内容，从微架构的角度，才能更理解并行。线程级并行可以是软件也可以有硬件支持。</p>
<p>（2）并行的两大分类</p>
<p>既然提到了微架构，就不得提一下并行的两大分类，微架构中经常将并行分为两大类：时间并行和空间并行。时间并行指的是流水线并行，空间并行包括指令并行、数据并行和线程并行。</p>
<p>更多关于以微架构的角度讨论这几个并行，参考相关的书籍，入门推荐《大话处理器》。</p>
<p>（3）指令级并行</p>
<p>所谓指令级并行，是指处理器能同时运行多条指令。</p>
<p>一般而言，如果程序中相邻的一组指令是相互独立的，即不竞争同一个功能部件、不相互等待对方的运算结果、不访问同一个存储单元，那么它们就可以在处理器内部并行地执行。</p>
<p>超标量（Superscalar）技术 和 超长指令字（Very Long Instruction Word, VLIW）技术是目前最基本的两类指令级并行技术。前者的特点是采用普通的指令，设置多条并行工作的指令流水线；后者的特点是：将若干条普通指令组装在一起，形成一条“超级指令”。这条“超级指令”包含多个不同操作码，这些操作码分别处理不同的操作数。对应这些操作码，一一对应地设置相应的功能部件。这样，只要取指令一次、分析指令一次，VLIW 技术就可以实现对多个不同的操作数，同时进行不同的处理/计算。目前，主流的微处理器都采用了超标量技术。</p>
<p>当然，现代处理器有很多能帮助其进行指令并行的设计，比如乱序执行、寄存器重命名等技术。指令级命令，需要依赖于具体的硬件支持，以及编译器支持。通常，我们需要依赖编译器的优化来生成指令级并行的代码，当然，对于有些情况，编译器需要我们的帮助，更容易生成指令级并行的代码，具体需要根据编译器的实现。</p>
<p>参考<a href="http://www.docin.com/p-148703990.html">http://www.docin.com/p-148703990.html</a>介绍用软件方法开发指令级并行代码，其实，其分析的正是编译器生成指令级并行的例子（流水线调度和循环展开等）。</p>
<p>（3）数据级并行</p>
<p>所谓数据级并行，是指处理器能同时运行多条数据。数据并行需要从SIMD、MMX、SSE等谈起了。</p>
<p>SIMD：single instruction multiple data，单指令多数据，即同一操作会重复处理多个数据，一条语句处理多个数据的指令，就是SIMD指令。SIMD指令的出现是从多媒体时代开始的，由于多媒体中很多数据的处理就是SIMD的模型，所以，诞生了SIMD指令。现在的高性能处理器都支持SIMD指令，Intel从1996年开始增加MMX（MultiMedia eXtensions）指令集（也即SIMD指令），后来逐步增加了SSE（Streaming SIMD Extensions）、SSE2、SSE3、SSSE3、SSE4.1、SSE4.2、AVX（Advanced Vector Extensions）指令集。所以说，数据级并行，也是依靠处理器的指令集完成了。数据并行的模型包括垂直计算形式、水平计算形式、标量计算模式，图解可参考《大话处理器》的相关内容。</p>
<p>简单的理解，向量a[N],b[N],c[N]，那么</p>
<p>1. 垂直计算模式：a[i] op b[i] = c[i]</p>
<p>2. 水平计算模式：a[i] op a[i+1] = c[i] (前半部分) b[i] op b[i+1] = c[i] (后边部分)，这里的前半部分后半部分并不是严格的，得看指令会如何处理，总是，垂直计算方式，操作数来自于不同的源，水平计算方式，操作数可以来自于同一个源。</p>
<p>3. 标量计算模式：a[0] op b[0] = c[0]，其余不变。</p>
<p>对于多媒体的计算和科学计算，存在大量类似的计算，所以说SIMD能极大的提高计算性能。</p>
<p>当然，数据并行，比如垂直计算模式，最常见的情况，就是一个for循环了。</p>
<p>for(int i = 0;i&lt; N;i ++) c[i] = a[i] + b[i];</p>
<p>这样的代码就能生成SIMD指令，那么是不是这么一个循环，直接一条指令搞定！当然不是，并行是有限制的，能接受的N不可能无限大！对于不同的指令集，一次数据并行能接受的数据长度是一定的，对于AVX指令集，能接受的长度为256字节。所以，可以对这样的循环进行优化，比如：</p>
<p>for(int i = 0;i &lt; N;i +=4) { c[i] = a[i] + b[i]; c[i+1] = a[i+1] + b[i+1]; c[i+2] = a[i+2] + b[i+2]; c[i+3] = a[i+3] + b[i+3]; }</p>
<p>这样编译器就能很容易的生成SIMD指令（具体需要依赖编译器的实现，这里的4也是一个例子，前提是数组a/b/c的数据元素乘以4为SIMD指令集能接受一次运算的长度）</p>
<p>（4）线程级并行</p>
<p>线程并行是一种更高层的数据并行，是一种分时复用的思想。线程级并行可以依靠操作系统（软件）来完成，但是现在的处理器，硬件也会为线程并行提供帮助，从而提高线程并行的效率。</p>
<p>更多内容，参考《大话处理器》或者其他关于微架构的资料。</p>
<p>只有了解和理解了并行的这些概念，才能更好的理解编译器优化的工作，也就能更好的让我们写出更容易让编译器生成并行化代码的代码。</p>
]]></content:encoded>
			<wfw:commentRss>http://software.intel.com/zh-cn/blogs/2011/12/02/400009299/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

