Redian新闻
>
Grand Central Dispatch:迎接挑战【12/23】
avatar
Grand Central Dispatch:迎接挑战【12/23】# Apple - 家有苹果
m*1
1
大家讨论下吧:
电面后的讨论是利大于蔽还是蔽大于利? 并以经验和道理辅助说明.
avatar
a*a
2
http://bbs.weiphone.com/read.php?tid=517864
Mac OS X 10.6即所谓的Snow Leopard操作系统已正式发售。一如既往,Apple产品
光鲜的外表下凝聚了太多艰辛的劳作。ArsTechnic的John Siracusa以其独特的、专业
的、全面的视角深入翔实地体验这款最新的操作系统。
Weiphone.com将对该综述进行翻译整理并独家连载。欢迎关注
Grand Central Dispatch
上一篇连载《并行难题:一封19年前的挑战书(连载11/23)》中,我们讨论了
并行编程(parallel programming)的问题,以及该问题所导致的另一个更为深远问题,
那就是:近一二十年以来,尽管计算机硬件的发展已经迈上了一个新的台阶,然而“软
件”层面的发展却裹足不前,最终成为了限制计算机性能的主要因素之一。
针对这一问题,Snow Leopard的应对方案是Grand Central Dispatch(GCD)。
GCD是刚刚发布的Snow Leopard的一项新特性,是一种简化并行编程的工具,可供Mac
OS X下任何基于C的程序语言使用,如C++,Objective-C以及Objective-C++。
对于GCD,首先需要明确的是,这并不是一个新的Cocoa框架或者类似的东西,
而是一个嵌入操作系统最底层的C语言库。GCD构建在libSystem内,整合了libC以及其
他一些userspace底层的代码。
引用
译注:
libC(C Standard library):由一整套ISO C标准组成,描述了用来执行一般操
作的头文件(header file)和库程序(library routine),诸如输入/输出以及字符串操
作等。C standard library也是一种接口标准(interface standard),并不是C语言程
序连接指令所需的库。详情请参阅wikipedia
userspace(也称作userland):常规操作系统中,虚拟内存通常被划分为内核
空间(kernel space)以及用户空间(user space)。内核空间被严格保留用来运行内核、
内核扩展(kernel extension)以及一些设备驱动。相反,用户空间则是内存区域中用来
运行所有用户程序的空间。每一个用户空间进程通常运行在其自己的虚拟内存空间内,
并且通常情况下不允许访问其他进程的空间,这也是现今主流操作系统中内存保护和特
权分离(privilege separation)机制的基础。 详情请参阅wikipedia
如果您希望在您的程序中使用GCD,您不必链接一个新的库,只需添加“#
include ”即可。
队列(queue)与线程(thread)
引用
译注:
队列(queue):一种特殊的集合,其中的实体按照特定的顺序排列,仅允许从
末端位置添加并从前端位置移除,为其赋予了“先入先出(First-In-First-Out)”的特
性。在FIFO数据结构中,首先添加的元素将被率先移除。队列是一种线形数据结构。队
列广泛应用于计算机程序中,作为一种数据结构与访问程序(access routine)相耦合。
详情请参阅wikipedia。
线程(thread):计算机科学中,一个执行线程源于一个程序的分支(当进程分支时会创
建一个自身的副本,即从夫线程创建一个子线程),并产生两个或多个并行任务。在不
同的操作系统中,线程或进程的执行可能存在差异,但是在大多数情况下,线程是包括
在进程内部的。多个线程可以存在于一个进程内并共享系统资源,如内存等,而不同的
进程却无法共享这些资源。在一个多处理器(multiprocessor)或多核(multi-core)系统
中,通常都会有线程或任务同时运行,每一个处理器或内核运行一个特定的线程或任务
。不同的程序语言对于线程的支持多种多样。许多语言都支持多线程,然而并非所有的
语言都允许同时执行多个线程。许多现代操作系统直接支持时间片(time-sliced)以及
多处理器线程。操作系统内核允许程序员通过系统调用接口(system call interface)
来操控线程。详情请参考wikipedia。
GCD构建于几个简单的实体之上。让我们从队列(queue)谈起。在队列的FIFO(
First in, First out)顺序中,任务首先入队列(enqueue),然后出队列(dequeue)。出
队列(dequeue)意味着该任务被传递至线程并执行。
尽管GCD队列会按照FIFO顺序将任务传递至线程,然而许多来自同一队列的任
务仍然有可能在任何给定的时间内并行运行。例如这段动画所展示的:
点击播放flash
请注意,这里任务B是在任务A之前完成的。尽管出队列的顺序由FIFO决定,然
而任务的完成顺序却不一定如此。同时,这里的队列中有3个任务,而只使用了两个线
程。这是我们将要讨论的GCD的一个重要特色。
但是首先,我们来看一看另外一种队列。一个串行队列(serial queue)运行起
来和普通队列一样,但是其每次只能运行一个任务,这就意味着一系列任务完成的顺序
将和FIFO顺序一致。对串行队列来说,每一个应用程序拥有一个绝对的“主队列”,即
运行于主线程上的主队列。
上面这段动画中展示了,线程可以根据需要而增加,并且在运行结束之后释放
空闲的线程。这就是GCD的一个重要特色,能够根据应用程序的实际需要调整线程数量
,提高工作效率。以传统的手工方式管理线程,最困难的部分莫过于,究竟需要创建多
少个线程才能使性能最大化。
来举一个例子。譬如一个程序可以被分割成八个独立的工作模块,而该程序在
一个八核计算机上创建了四个线程,是否能够简单地说这个程序创建了过多或者过少的
线程了呢?这是个有趣的问题。答案的关键在于,与系统中正在执行的其他工作有关。
如果这八个核中的六个核已为其他的一些工作所占用(所饱和),那么创建四个
线程则意味着操作系统将周旋于这四个线程并浪费了不少时间,尽管这里有两个空闲的
内核。但是如果先前在执行的其他工作完成了,那么这时候实际上就有八个空闲的内核
而只有四个线程,使将近一半系统资源闲置。
除了一些极其特殊的程序之外,程序员无法事先知道究竟需要创建多少线程。
对于特定的计算机来说,有多少内核正在使用?如果有更多的核进入闲置状态,那么程
序又如何得知并适时调整以使用这些闲置的资源?
底线在于,在任意给定时间,最优化的线程数目通过一个单一的、全局的实体
来确定。在Snow Leopard中,这个实体就是GCD。如果没有队列运行那么GCD将保持零线
程;一旦有任务出队列,GCD将创建新的线程优化硬件资源的使用。GCD知道系统拥有多
少内核,也知道当前执行的任务究竟需要多少线程。当一个队列中的任务执行结束并不
再需要线程时,GCD会调配线程至其他出队列并即将运行的任务。
另外,这里还存在更为深入的优化。在Mac OS X中,线程实际上是相对重要的
(heavyweight)。每一个线程维持其自身的一系列注册值(register value),堆栈指针(
stack pointer)程序计算器(program counter),用来追踪其安全凭证(security
credentials)的内核数据结构(kernel data structures),调度优先级(scheduling
priority),等等。这就意味着,每个线程本身就会有超过512KB的系统资源开销。设想
一下,如果创建一千个线程,就会耗用大概半GB的内存和内核资源,更不要提线程中的
具体数据了。
而队列本身是相对不那么重要的(lightweight),开发者可以根据需要随意创
建,一百个甚至一千个都没问题。在上面的动画中,该队列被分配了两个线程用来运行
其三个任务,在其中一个线程上执行了两个任务。线程不仅在内存开销上是
heavyweight的,创建线程本身也会耗费一定的系统资源。为每一个任务创建一个新的
线程显然是最糟糕的选择。而GCD能够合理调配使每一个线程执行多个任务,就整个系
统而言,这本身就是非常高校的。
通过GCD,我们在上面提到的一个问题迎刃而解——程序员不必纠结于究竟应
该创建多少个线程,而是应该集中精力来优化并行算法。如果程序需要500个并行任务
,那么程序员可以创建500个GCD队列并在其中分配自己的工作,然后GCD会根据具体需
要创建线程。而且,线程数目会根据系统实际状况进行动态调整。
不得不指出很重要的一点,由于新推出的计算机往往配备了越来越多的CPU内
核,或许程序员根本不必改动他们的程序。GCD将自然地应用一切可用的计算资源,以
满足程序员最初创建的队列数目并实现最优化并行运行。
而且,GCD队列可以在任意复杂的有向非循环图(directed acyclic graph)中
安排和调配。队列层次(queue hierarchied)结构可以用来将来自不同的子系统中的任
务导入一系列中央控制队列中,或者迫使一系列普通队列成为一个串行队列,从而有效
地间接串行化。
引用
译注:
有向非循环图(directed acyclic graph,DAG):数学上,有向非循环图是一
种没有有向环(directed cycle)的有向图,是一个顶点(vertex,复数vertices)和有向
边(directed edge)的集合,每一个有向边从一个顶点指向另一个顶点,因此无法从一
个特定顶点沿特定顺序出发最终回到该顶点。我已经挂了您要是没挂请查阅wikipedia
同时,队列优先级有几个不同的级别,规定了线程被分配的频率和紧要程度。
线程可以被中止,恢复或者取消。线程也可以被分组归类,允许所分配到该组的任务都
能够作为一个单元被跟踪。
所以说,GCD通过队列和线程形成了一种简洁而又极为实用的逻辑结构。
最后让我们看一看Apple自己是怎么描述GCD的:
avatar
n*r
3
得体的follow up没有什么坏处

【在 m*********1 的大作中提到】
: 大家讨论下吧:
: 电面后的讨论是利大于蔽还是蔽大于利? 并以经验和道理辅助说明.

avatar
O*t
4
应该可以说谢谢啥之类的吧,
也可强调下你可以和学校的合作,启动会很快等,但要非常的小心.
人家会想:为何电话中不讲清楚?

【在 m*********1 的大作中提到】
: 大家讨论下吧:
: 电面后的讨论是利大于蔽还是蔽大于利? 并以经验和道理辅助说明.

相关阅读
logo
联系我们隐私协议©2024 redian.news
Redian新闻
Redian.news刊载任何文章,不代表同意其说法或描述,仅为提供更多信息,也不构成任何建议。文章信息的合法性及真实性由其作者负责,与Redian.news及其运营公司无关。欢迎投稿,如发现稿件侵权,或作者不愿在本网发表文章,请版权拥有者通知本网处理。