<?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; SMP</title>
	<atom:link href="http://www.speedvi.net/tag/smp/feed" rel="self" type="application/rss+xml" />
	<link>http://www.speedvi.net</link>
	<description>为者常成 行者常至</description>
	<lastBuildDate>Sat, 12 Jun 2010 06:30:36 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>在SMP系统使用多线程需要注意的事情</title>
		<link>http://www.speedvi.net/2010/01/28/202.html</link>
		<comments>http://www.speedvi.net/2010/01/28/202.html#comments</comments>
		<pubDate>Thu, 28 Jan 2010 03:18:55 +0000</pubDate>
		<dc:creator>行者</dc:creator>
				<category><![CDATA[操作系统]]></category>
		<category><![CDATA[SMP]]></category>
		<category><![CDATA[多线程]]></category>
		<category><![CDATA[实时系统]]></category>
		<category><![CDATA[系统内核]]></category>

		<guid isPermaLink="false">http://www.speedvi.net/2010/01/28/202.html</guid>
		<description><![CDATA[　　尽管你一般可以忽略你的系统是运行在SMP架构上还是单处理器上，不过还是有些事情会影响到你。不幸的是，这些事情都是低概率事件，它们可能在你的开发阶段没有出现，但是可能在测试、演示或更糟的，在实际应用中出现。在编程的时候花些时间做些防御性的措施可以在后续的阶段减少问题的发生几率。 　　下面就是你可能在SMP系统上遇到的事情： 多个线程确实可以也能同时运行——不过依赖于像FIFO调度、优先级这些东西来同步是不允许的； 多线程可与中断服务程序（ISR）同时运行——也就是说你不但要保护线程不受ISR的影响，也要保护中断服务程序不受线程的影响； 有些操作你期望是最小单元的、单步的，可能会依赖于操作与处理器的不同而不是最小单元的、单步的。这类的操作包括了需要“读取-修改-写入”周期操作的（例如：++，&#8211;，&#124;=，&#38;=等等）。你可以查找&#60;atomic.h&#62;文件来查找对应的最小单元替换函数。（这也不是只有SMP系统的问题，大多数的RISC处理器对上面的胆码也不是按照最小单元处理的） Related posts:进程间通信 　　进程间通信的缩写是IPC，不缩写的就是Interprocess Communication。进程间通信是将实时操作系统微内核转换为全面的POSIX系统中的基本元素之一。当多种服务进程添加到微内核的时候，进程间通信就是将这些元件结合为一个整体的“胶水”。 　　在UNIX操作系统中消息传递是IPC的主要形式，除此之外还有其他形式的IPC。除非特别声明，这些其他形式的IPC都是建立在本地的消息传递机制之上的。这里使用的策略就是创建一个简单、强健的IPC服务，这个服务可以在微内核里面通过简化代码就可以调整其性能，之后功能更多的IPC服务就可以以此为基础加以完成。 　　通过将高级的IPC服务（例如基于消息的管道(pipes)以及先进先出(FIFO)）与大内核的同类服务进行性能测试比较得到的结果是其性能是相当的。 　　UNIX提供的IPC形式包括了基于内核的消息传递(Message-passing)、基于内核的信号(Signals)、基于外部线程的POSIX消息队列(POSIX message queues)、基于线程管理器的共享内存(Shared memory)、基于外部线程的管道(Pipes)以及基于外部线程的先进先出(FIFOs)。系统设计师可以基于带宽需求、队列需求、网络透明性等因素来从这些服务中挑选合适的形式。选择某种形式的副作用是复杂的，不过灵活性是可以保证的。 　　作为定义UNIX系统内核的工程努力的一部分，将消息传递作为IPC的基础元素是经过深思熟虑的。作为进程间消息传递的一种形式，消息传递是用来同步与复制数据的。 同步信息传递... 进程间通信的消息复制 　　在UNIX中，消息服务直接从一个线程的地址空间复制消息到另一个线程的地址空间，没有也不通过中间的缓存，这样的话消息传递的性能就接近了底层硬件所支持的最大内存带宽了。对于消息的内容，系统内核没有赋予其特别的含义，只有发送者与接收者才相互的为其约定了特殊的意义。尽管如此，系统也提供了“良好定义”的消息类型以便用户编写的进程或线程可以用来扩充或替换系统提供的服务。 　　消息原(message primitives)支持多段传输，也就是说从一个线程的地址空间传送到另一个线程的消息不必一定位于单独、连续的缓存上。发送与接收线程都可以指定一个向量表来记录发送以及接收的消息片断在内存中的地址。发送与接收者的消息的每个片断的大小可以是不同的。 　　消息的多段传输可以让消息头块与消息数据块分离的消息在传输时没有必要执行数据拷贝操作以使其变为一个连续的消息，从而就避免了浪费性能的拷贝操作。另外，如果底层数据结构是环形缓存的话，指定为三段的消息就能够让在这个环形缓存中一个头与两个不相交范围的数据可以在一个元消息(atomic message)中完成传输。硬件上与其等同的就是DMA的发散/聚集功能。 　　多段传送的示意图如下：   多段传送也被大量用于文件系统中。在执行读取操作时，通过使用具有n段数据消息，数据被从文件系统缓存中直接读取到应用程序中。每段都指向了缓存并用来补偿每个缓存块在内存中不是连续的实际。 　　例如，假如每个缓存块大小为512的字节，如果需要读取1454个字节就可以用一个5段的消息完成。示意图如下： 　　由于数据是在地址空间直接复制的（而不只是做页面表操作），消息可以在在堆栈中轻易的分配而不需要从用于内存管理器页面反转(MMU... 在单CPU上使用多线程 　　假设我们略微修改我们的例子，让它能演示有些时候在单处理器上使用多线程的好处。 　　在这个修改的例子里面，网络中的一个节点负责计算扫描线（与前面的图像例子一样）。不过，当一个扫描线的计算结束后，它的数据就通过网络发送到另外一个节点。下面是我们修改后的main()函数： int main (int argc, char **argv) { int...


Related posts:<ol><li><a href='http://www.speedvi.net/2009/09/25/160.html' rel='bookmark' title='进程间通信'>进程间通信</a> <small>　　进程间通信的缩写是IPC，不缩写的就是Interprocess Communication。进程间通信是将实时操作系统微内核转换为全面的POSIX系统中的基本元素之一。当多种服务进程添加到微内核的时候，进程间通信就是将这些元件结合为一个整体的“胶水”。 　　在UNIX操作系统中消息传递是IPC的主要形式，除此之外还有其他形式的IPC。除非特别声明，这些其他形式的IPC都是建立在本地的消息传递机制之上的。这里使用的策略就是创建一个简单、强健的IPC服务，这个服务可以在微内核里面通过简化代码就可以调整其性能，之后功能更多的IPC服务就可以以此为基础加以完成。 　　通过将高级的IPC服务（例如基于消息的管道(pipes)以及先进先出(FIFO)）与大内核的同类服务进行性能测试比较得到的结果是其性能是相当的。 　　UNIX提供的IPC形式包括了基于内核的消息传递(Message-passing)、基于内核的信号(Signals)、基于外部线程的POSIX消息队列(POSIX message queues)、基于线程管理器的共享内存(Shared memory)、基于外部线程的管道(Pipes)以及基于外部线程的先进先出(FIFOs)。系统设计师可以基于带宽需求、队列需求、网络透明性等因素来从这些服务中挑选合适的形式。选择某种形式的副作用是复杂的，不过灵活性是可以保证的。 　　作为定义UNIX系统内核的工程努力的一部分，将消息传递作为IPC的基础元素是经过深思熟虑的。作为进程间消息传递的一种形式，消息传递是用来同步与复制数据的。 同步信息传递...</small></li>
<li><a href='http://www.speedvi.net/2009/09/25/163.html' rel='bookmark' title='进程间通信的消息复制'>进程间通信的消息复制</a> <small>　　在UNIX中，消息服务直接从一个线程的地址空间复制消息到另一个线程的地址空间，没有也不通过中间的缓存，这样的话消息传递的性能就接近了底层硬件所支持的最大内存带宽了。对于消息的内容，系统内核没有赋予其特别的含义，只有发送者与接收者才相互的为其约定了特殊的意义。尽管如此，系统也提供了“良好定义”的消息类型以便用户编写的进程或线程可以用来扩充或替换系统提供的服务。 　　消息原(message primitives)支持多段传输，也就是说从一个线程的地址空间传送到另一个线程的消息不必一定位于单独、连续的缓存上。发送与接收线程都可以指定一个向量表来记录发送以及接收的消息片断在内存中的地址。发送与接收者的消息的每个片断的大小可以是不同的。 　　消息的多段传输可以让消息头块与消息数据块分离的消息在传输时没有必要执行数据拷贝操作以使其变为一个连续的消息，从而就避免了浪费性能的拷贝操作。另外，如果底层数据结构是环形缓存的话，指定为三段的消息就能够让在这个环形缓存中一个头与两个不相交范围的数据可以在一个元消息(atomic message)中完成传输。硬件上与其等同的就是DMA的发散/聚集功能。 　　多段传送的示意图如下：   多段传送也被大量用于文件系统中。在执行读取操作时，通过使用具有n段数据消息，数据被从文件系统缓存中直接读取到应用程序中。每段都指向了缓存并用来补偿每个缓存块在内存中不是连续的实际。 　　例如，假如每个缓存块大小为512的字节，如果需要读取1454个字节就可以用一个5段的消息完成。示意图如下： 　　由于数据是在地址空间直接复制的（而不只是做页面表操作），消息可以在在堆栈中轻易的分配而不需要从用于内存管理器页面反转(MMU...</small></li>
<li><a href='http://www.speedvi.net/2010/01/27/201.html' rel='bookmark' title='在单CPU上使用多线程'>在单CPU上使用多线程</a> <small>　　假设我们略微修改我们的例子，让它能演示有些时候在单处理器上使用多线程的好处。 　　在这个修改的例子里面，网络中的一个节点负责计算扫描线（与前面的图像例子一样）。不过，当一个扫描线的计算结束后，它的数据就通过网络发送到另外一个节点。下面是我们修改后的main()函数： int main (int argc, char **argv) { int...</small></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>　　尽管你一般可以忽略你的系统是运行在SMP架构上还是单处理器上，不过还是有些事情会影响到你。不幸的是，这些事情都是低概率事件，它们可能在你的开发阶段没有出现，但是可能在测试、演示或更糟的，在实际应用中出现。在编程的时候花些时间做些防御性的措施可以在后续的阶段减少问题的发生几率。</p>
<p>　　下面就是你可能在SMP系统上遇到的事情：</p>
<ul>
<li>多个线程确实可以也能同时运行——不过依赖于像FIFO调度、优先级这些东西来同步是不允许的；</li>
<li>多线程可与中断服务程序（ISR）同时运行——也就是说你不但要保护线程不受ISR的影响，也要保护中断服务程序不受线程的影响；</li>
<li>有些操作你期望是最小单元的、单步的，可能会依赖于操作与处理器的不同而不是最小单元的、单步的。这类的操作包括了需要“读取-修改-写入”周期操作的（例如：++，&#8211;，|=，&amp;=等等）。你可以查找&lt;atomic.h&gt;文件来查找对应的最小单元替换函数。（这也不是只有SMP系统的问题，大多数的RISC处理器对上面的胆码也不是按照最小单元处理的）</li>
</ul>


<p>Related posts:<ol><li><a href='http://www.speedvi.net/2009/09/25/160.html' rel='bookmark' title='进程间通信'>进程间通信</a> <small>　　进程间通信的缩写是IPC，不缩写的就是Interprocess Communication。进程间通信是将实时操作系统微内核转换为全面的POSIX系统中的基本元素之一。当多种服务进程添加到微内核的时候，进程间通信就是将这些元件结合为一个整体的“胶水”。 　　在UNIX操作系统中消息传递是IPC的主要形式，除此之外还有其他形式的IPC。除非特别声明，这些其他形式的IPC都是建立在本地的消息传递机制之上的。这里使用的策略就是创建一个简单、强健的IPC服务，这个服务可以在微内核里面通过简化代码就可以调整其性能，之后功能更多的IPC服务就可以以此为基础加以完成。 　　通过将高级的IPC服务（例如基于消息的管道(pipes)以及先进先出(FIFO)）与大内核的同类服务进行性能测试比较得到的结果是其性能是相当的。 　　UNIX提供的IPC形式包括了基于内核的消息传递(Message-passing)、基于内核的信号(Signals)、基于外部线程的POSIX消息队列(POSIX message queues)、基于线程管理器的共享内存(Shared memory)、基于外部线程的管道(Pipes)以及基于外部线程的先进先出(FIFOs)。系统设计师可以基于带宽需求、队列需求、网络透明性等因素来从这些服务中挑选合适的形式。选择某种形式的副作用是复杂的，不过灵活性是可以保证的。 　　作为定义UNIX系统内核的工程努力的一部分，将消息传递作为IPC的基础元素是经过深思熟虑的。作为进程间消息传递的一种形式，消息传递是用来同步与复制数据的。 同步信息传递...</small></li>
<li><a href='http://www.speedvi.net/2009/09/25/163.html' rel='bookmark' title='进程间通信的消息复制'>进程间通信的消息复制</a> <small>　　在UNIX中，消息服务直接从一个线程的地址空间复制消息到另一个线程的地址空间，没有也不通过中间的缓存，这样的话消息传递的性能就接近了底层硬件所支持的最大内存带宽了。对于消息的内容，系统内核没有赋予其特别的含义，只有发送者与接收者才相互的为其约定了特殊的意义。尽管如此，系统也提供了“良好定义”的消息类型以便用户编写的进程或线程可以用来扩充或替换系统提供的服务。 　　消息原(message primitives)支持多段传输，也就是说从一个线程的地址空间传送到另一个线程的消息不必一定位于单独、连续的缓存上。发送与接收线程都可以指定一个向量表来记录发送以及接收的消息片断在内存中的地址。发送与接收者的消息的每个片断的大小可以是不同的。 　　消息的多段传输可以让消息头块与消息数据块分离的消息在传输时没有必要执行数据拷贝操作以使其变为一个连续的消息，从而就避免了浪费性能的拷贝操作。另外，如果底层数据结构是环形缓存的话，指定为三段的消息就能够让在这个环形缓存中一个头与两个不相交范围的数据可以在一个元消息(atomic message)中完成传输。硬件上与其等同的就是DMA的发散/聚集功能。 　　多段传送的示意图如下：   多段传送也被大量用于文件系统中。在执行读取操作时，通过使用具有n段数据消息，数据被从文件系统缓存中直接读取到应用程序中。每段都指向了缓存并用来补偿每个缓存块在内存中不是连续的实际。 　　例如，假如每个缓存块大小为512的字节，如果需要读取1454个字节就可以用一个5段的消息完成。示意图如下： 　　由于数据是在地址空间直接复制的（而不只是做页面表操作），消息可以在在堆栈中轻易的分配而不需要从用于内存管理器页面反转(MMU...</small></li>
<li><a href='http://www.speedvi.net/2010/01/27/201.html' rel='bookmark' title='在单CPU上使用多线程'>在单CPU上使用多线程</a> <small>　　假设我们略微修改我们的例子，让它能演示有些时候在单处理器上使用多线程的好处。 　　在这个修改的例子里面，网络中的一个节点负责计算扫描线（与前面的图像例子一样）。不过，当一个扫描线的计算结束后，它的数据就通过网络发送到另外一个节点。下面是我们修改后的main()函数： int main (int argc, char **argv) { int...</small></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.speedvi.net/2010/01/28/202.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

