精华内容
下载资源
问答
  • 并行设计模式能够降低并行编程的难度与复杂度。针对科学与工程计算领域大量耗时的数据密集型应用的计算,提出了一种能够适用于阵列数据划分应用的FJRR并行设计模式;鉴于开发者更习惯串行编程,在FJRR模式中提出并...
  • 根据该模式数值计算的特点提出了一种并行求解三对角方程组的新方法,相对于传统算法编程简单而且并行效率更高;负载平衡是并行程序性能优化首先要解决的问题,以水格点的个数作为任务分解的标准,实现了较好的负载...
  • mpi-2.pdf 消息传递并行编程环境MPI.pdf MPI并行程序设计.pdf 并行编程模型研究文档.pdf 消息传递并行编程环境MPI (1).pdf
  • 利用并行计算中的OpenMP多核编程环境,采用曙光16核服务器为硬件平台,实现对动态模式识别算法的快速性;同时,以压气机Mansoux模型为应用背景,把确定学习理论的动态模式识别方法应用到压气机旋转失速/喘振的快速...
  • 3.5.3 安全发布的常用模式 3.5.4 事实不可变对象 3.5.5 可变对象 3.5.6 安全地共享对象 第4章 对象的组合 4.1 设计线程安全的类 4.1.1 收集同步需求 4.1.2 依赖状态的操作 4.1.3 状态的所有权 4.2 实例...
  • 为了充分利用多核处理器的硬件资源和计算能力来提高图像匹配应用的实时性,通过对自适应阈值SSDA图像匹配算法原理的分析,基于任务分解的多核并行编程模式思想,设计了一种自适应阈值SSDA图像匹配并行算法,并在多核...
  • 提出一种统一的并行计算模型LogGP-U(Unified LogGP),它是一个基于LogGP的并行计算模型,给出在几种...用这个模型分析了cannon矩阵乘在几种编程模式下的理论性能,并在曙光4000A集群上进行验证LogGP-U模型的有效性。
  • 本书介绍了如何通过Intel线程构建模块来最大限度地...书中包含了大量的示例和丰富的资料,给出了常见的使用模式,揭示了TBB中的精彩之处,并且还提供了一些指导意见,来在不同的并行编程方式上进行选择以获得最佳的性能
  • Tcl_TK编程权威指南pdf

    热门讨论 2011-03-25 09:30:55
    Tcl_TK编程权威指南pdf 内容简介回到顶部↑Tcl/Tk是第一种能通过Windows、Macintosh和Solaris等主要平台处理企业级任务的脚本语言。本书共分为55章,依次详细讲述了Tcl基础、Tcl高级特性、TK基础、TK组件、TK详解、...
  • GPU编程与优化 大众高性能计算(高清完整版) pdf 版。 本书第一篇系统地介绍GPU编程的相关知识,帮助读者快速入门,并构建GPU知识体系;第二篇和第三篇给出大量实例,对每个实例进行循序渐进的并行和优化实践,为读者...
  • 第2章 并行编程平台 2.1 隐式并行:微处理器体系结构的发展趋势 2.1.1 流水线与超标量执行 2.1.2 超长指令字处理器 2.2 内存系统性能的局限 2.2.1 使用高速缓存改善有效内存延迟 2.2.2 内存带宽的影响 2.2.3 ...
  • 第3 章面向对象编程.............................87 3.1 继承........................................................ 87 3.2 多接口................................................ 129 3.2.1 对象接口........
  • 第四篇总结影响GPU性能的关键要素(执行核心和存储体系),量化测评GPU的核心性能参数,给出CPU/GPU异构系统上覆盖完全的各种混合并行模式及其实践,帮助读者真正透彻理解GPU。 本书适合作为计算机及相关专业...

    内容简介

    本书第一篇系统地介绍GPU编程的相关知识,帮助读者快速入门,并构建GPU知识体系;第二篇和第三篇给出大量实例,对每个实例进行循序渐进的并行和优化实践,为读者提供GPU编程和优化参考;第四篇总结影响GPU性能的关键要素(执行核心和存储体系),量化测评GPU的核心性能参数,给出CPU/GPU异构系统上覆盖完全的各种混合并行模式及其实践,帮助读者真正透彻理解GPU。 本书适合作为计算机及相关专业的教材,也可作为GPU程序开发人员和科研人员的参考书。本书封面贴有清华大学出版社防伪标签,无标签者不得销售。

    目录

    第一篇理论篇

    第1章高性能计算概述3

    1.1高性能计算概念辨析3

    1.1.1并行计算、高性能计算和超级计算3

    1.1.2超级计算机与超级计算中心4

    1.2计算科学5

    1.3高性能计算发展史5

    1.4高性能计算简介6

    1.5向量机与阵列机8

    1.6本章小结9

    第2章GPU概述10

    2.1GPU是什么10

    2.2协处理器10

    2.3GPU与显卡的关系11

    2.4GPU/显卡购买注意事项11

    2.5为什么要学GPU编程12

    2.6GPU与CPU辨析13

    2.7GPU发展简史14

    2.8GPU编程方法14

    2.9CPU/GPU异构系统16

    第3章GPU硬件架构17

    3.1GPU架构17

    3.1.1Tesla架构18

    3.1.2Fermi架构20

    3.1.3Kepler架构21

    3.1.4Maxwell架构23

    3.1.5Pascal架构243.2Kernel的硬件映射28

    3.3GPU存储体系29

    3.4GPU计算能力30

    GPU编程与优化——大众高性能计算目录第4章GPU软件体系33

    4.1GPU软件生态系统33

    4.2CUDA Toolkit34

    4.2.1NVCC编译器34

    4.2.2cuobjdump35

    4.3CUDA环境安装36

    4.3.1Windows 7安装CUDA 4.236

    4.3.2Linux下安装CUDA38

    第5章CUDA C编程41

    5.1CUDA编程模型41

    5.2CUDA编程七步曲42

    5.3驱动API与运行时API42

    5.4CUDA运行时函数43

    5.4.1设备管理函数43

    5.4.2存储管理函数45

    5.4.3数据传输函数48

    5.4.4线程管理函数51

    5.4.5流管理函数52

    5.4.6事件管理函数52

    5.4.7纹理管理函数53

    5.4.8执行控制函数55

    5.4.9错误处理函数55

    5.4.10图形学互操作函数57

    5.4.11OpenGL互操作函数58

    5.4.12Direct3D互操作函数59

    5.5CUDA C语言扩展60

    5.6gridblockthread三维模型61

    第二篇入门篇

    第6章向量加法67

    6.1向量加法及其串行代码67

    6.2单block单thread向量加68

    6.3单block多thread向量加68

    6.4多block多thread向量加69

    6.5CUBLAS库向量加法70

    6.6实验结果分析与结论71

    6.6.1本书实验平台71

    6.6.2实验结果71

    6.6.3结论71

    6.7知识点总结72

    6.8扩展练习75

    第7章归约: 向量内积76

    7.1向量内积及其串行代码76

    7.2单block分散归约向量内积77

    7.3单block低线程归约向量内积78

    7.4多block向量内积(CPU二次归约)79

    7.5多block向量内积(GPU二次归约)81

    7.6基于原子操作的多block向量内积81

    7.7计数法实现多block向量内积84

    7.8CUBLAS库向量内积85

    7.9实验结果与结论86

    7.9.1实验结果86

    7.9.2结论86

    7.10归约的深入优化探讨87

    7.10.1block数量和thread数量对归约性能的影响87

    7.10.2算术运算优化88

    7.10.3减少同步开销89

    7.10.4循环展开90

    7.10.5总结91

    7.11知识点总结91

    7.12扩展练习94

    第8章矩阵乘法95

    8.1矩阵乘法及其3种串行代码95

    8.1.1一般矩阵乘法95

    8.1.2循环交换矩阵乘法97

    8.1.3转置矩阵乘法98

    8.1.4实验结果与最优串行矩阵乘99

    8.2grid线程循环矩阵乘法100

    8.3block线程循环矩阵乘法101

    8.4行共享存储矩阵乘法101

    8.5棋盘阵列矩阵乘法103

    8.6判断移除105

    8.7CUBLAS矩阵乘法106

    8.8实验结果分析与结论108

    8.8.1矩阵乘精度分析108

    8.8.2实验结果分析110

    8.8.3浮点运算能力分析111

    8.9行共享存储矩阵乘法改进111

    8.10知识点总结113

    8.11扩展练习115

    第9章矩阵转置116

    9.1矩阵转置及其串行代码116

    9.21D矩阵转置117

    9.32D矩阵转置118

    9.4共享存储2D矩阵转置119

    9.5共享存储2D矩阵转置diagonal优化120

    9.6实验结果分析与结论121

    9.7共享存储2D矩阵转置的深入优化122

    9.8知识点总结124

    9.9扩展练习125

    第三篇提高篇

    第10章卷积129

    10.1卷积及其串行实现129

    10.1.1一维卷积129

    10.1.2二维卷积131

    10.2GPU上1D卷积134

    10.3M常量1D卷积135

    10.4M共享1D卷积136

    10.5N共享1D卷积137

    10.6实验结果分析139

    10.6.1扩展法1D卷积实验结果分析139

    10.6.2判断法与扩展法1D卷积对比140

    10.6.3加速比分析141

    10.6.4线程维度对性能的影响141

    10.72D卷积的GPU移植与优化142

    10.7.1GPU上2D卷积142

    10.7.2M常量2D卷积143

    10.7.3M常量N共享2D卷积143

    10.7.42D卷积实验结果分析145

    10.8知识点总结145

    10.9扩展练习147

    第11章曼德博罗特集148

    11.1曼德博罗特集及其串行实现148

    11.2曼德博罗特集的GPU映射150

    11.3一些优化尝试及效果152

    11.3.1访存连续152

    11.3.2uchar4访存合并153

    11.3.34种零拷贝153

    11.3.4总结分析155

    11.4计算通信重叠优化156

    11.5突破kernel执行时间限制159

    11.6知识点总结160

    11.7扩展练习162

    第12章扫描: 前缀求和163

    12.1前缀求和及其串行代码163

    12.2KoggeStone并行前缀和164

    12.2.1直接KoggeStone分段前缀和164

    12.2.2交错KoggeStone分段前缀和165

    12.2.3完整KoggeStone前缀和166

    12.3BrentKung并行前缀和168

    12.3.1BrentKung分段前缀和169

    12.3.2两倍数据的BrentKung分段前缀和170

    12.3.3避免bank conflict的两倍数据BrentKung分段前缀和171

    12.3.4完整BrentKung前缀和173

    12.4warp分段的KoggeStone前缀求和174

    12.5实验结果分析与结论177

    12.6知识点总结179

    12.7扩展练习180第13章排序181

    13.1串行排序及其性能181

    13.1.1选择排序181

    13.1.2冒泡排序182

    13.1.3快速排序182

    13.1.4基数排序183

    13.1.5双调排序网络185

    13.1.6合并排序186

    13.1.7串行排序性能对比187

    13.2基数排序188

    13.2.1基数排序概述188

    13.2.2单block基数排序189

    13.2.3基于thrust库的基数排序196

    13.3双调排序网络197

    13.3.1双调排序网络概述197

    13.3.2单block双调排序网络199

    13.3.3多block双调排序网络202

    13.4快速排序206

    13.5合并排序207

    13.6实验结果分析与结论208

    13.7知识点总结209

    13.8扩展练习210

    第14章几种简单图像处理211

    14.1图像直方图统计211

    14.1.1串行直方图统计211

    14.1.2并行直方图统计211

    14.1.3实验结果与分析212

    14.2中值滤波213

    14.2.1串行中值滤波214

    14.2.21D并行中值滤波215

    14.2.3共享1D中值滤波216

    14.2.4双重共享1D中值滤波218

    14.2.52D并行中值滤波221

    14.2.6共享2D中值滤波222

    14.2.7共享2D中值滤波的改进227

    14.2.8实验结果与分析229

    14.3均值滤波231

    14.3.1串行均值滤波231

    14.3.2并行均值滤波232

    14.3.3实验结果与分析233

    第四篇核心篇

    第15章GPU执行核心237

    15.1概述237

    15.2算术运算支持238

    15.2.1整数运算238

    15.2.2浮点运算239

    15.3算术运算性能240

    15.4分支处理242

    15.5同步与测时246

    15.5.1同步246

    15.5.2测时247

    15.6数学函数247

    15.7warp与block原语249

    15.7.1warp原语249

    15.7.2block原语250

    15.8kernel启动、线程切换和循环处理251

    第16章GPU存储体系254

    16.1概述254

    16.2寄存器259

    16.3局部存储261

    16.4共享存储器264

    16.4.1共享存储使用264

    16.4.2bank conflict265

    16.4.3volatile关键字266

    16.4.4共享存储原子操作267

    16.5常量存储268

    16.6全局存储269

    16.6.1全局存储的使用269

    16.6.2全局存储的合并访问271

    16.6.3利用纹理缓存通道访问全局存储271

    16.7纹理存储273

    16.7.1CUDA数组273

    16.7.2纹理存储的操作和限制274

    16.7.3读取模式、纹理坐标、滤波模式和寻址模式276

    16.7.4表面存储278

    16.8主机端内存281

    16.9零拷贝操作283

    第17章GPU关键性能测评284

    17.1GPU性能测评概述284

    17.2GPU参数获取286

    17.2.1GPU选择286

    17.2.2详细设备参数获取287

    17.3精确测时方法汇总288

    17.3.1clock测时289

    17.3.2gettimeofday测时289

    17.3.3CUDA事件测时289

    17.3.4cutil库函数测时290

    17.4GPU预热与启动开销290

    17.5GPU浮点运算能力291

    17.6GPU访存带宽293

    17.7GPU通信带宽295

    17.8NVIDIA Visual Profiler296

    17.9程序性能对比约定298

    第18章CPUs和GPUs协同299

    18.1协同优化基点299

    18.1.1CPU并行矩阵乘基点299

    18.1.2GPU并行矩阵乘基点300

    18.2CPU/GPU协同300

    18.3多GPU协同305

    18.3.1CUDA版本306

    18.3.2OpenMP+CUDA308

    18.3.3MPI+CUDA311

    18.4CPUs/GPUs协同314

    18.4.1CUDA版本314

    18.4.2OpenMP+CUDA319

    18.4.3MPI+OpenMP+CUDA324

    18.5本章小结329

    附录

    附录A判断法1D卷积代码333

    附录A.1判断法1D卷积basic版333

    附录A.2判断法1D卷积constant版334

    附录A.3判断法1D卷积shared版336

    附录A.4判断法1D卷积cache版337

    附录B曼德博罗特集的系列优化代码340

    附录B.1完整版串行C代码340

    附录B.2cuda_1_0343

    附录B.3cuda_0_2345

    附录B.4cuda_zerocopy346

    附录B.5cuda_1_0_zerocopy348

    附录B.6cuda_0_0_zerocopy349

    附录B.7cuda_0_2_zerocopy351

    附录B.8cuda_2352

    附录B.9cuda_1_2354

    附录C几种图像处理完整源码357

    附录C.1BMP图像读写头文件357

    附录C.2图像直方图串行代码373

    附录C.3串行中值滤波代码374

    附录C.4并行均值滤波相关代码376

    附录Dnvprof帮助菜单383

    附录ENVCC帮助菜单388

    附录F几种排序算法源代码399

    附录F.1bitonic_sort_block函数399

    附录F.2GPU快速排序完整代码400

    附录F.3GPU合并排序完整代码408

    参考文献417

    文档截图

    展开全文
  • .NET Framework 4是该产品的另一个重要的版本,也引入了运行库的一个新版本4.0和C#的新版本4.0,提供了动态语言集成和大量用于并行编程的新库。.NET Framework 4.5基于4.0运行库的更新版本,包含了许多重要的新功能...
  • 个体之间的关系日益复杂,给传统的社会网络分析方式带来了新的挑战和机遇.MapReduce框架的产生解决了这种问题,它提供了简单的编程接口,隐藏了底层的细节,将程序员从传统的并行编程模式中解放出来.同时它的简单性也...
  • 对随机模式匹配算法进行了改进,并根据MPICH并行编程环境中任务间通信的特点,设计了一种基于MPICH的改进的随机模式匹配并行算法。根据运行在COW(工作站机群)上的进程数目将文本串进行重叠划分,每个进程完成一个...
  • 在医学图像分析中,图像配准通常是一个耗时的过程,不利于临床应用,为了加速医学图像的2D-3D配准过程,研究了CUDA的设计思想和编程方式,提出了一种基于CUDA并行编程模型的加速配准新技术,在构建的虚拟X线摄像系统...
  • 考察由CPU和GPU组成的异构并行系统中应用程序的容错,利用Charm 并行编程模型和CUDA的并行计算架构,对大规模计算宇宙学软件WIGEON进行重构。针对异构并行系统中存在的fail-stop硬件故障,设计并实现了内存检查点的...
  • 第四,介绍并行的基本设计模式及Java 8对并行程序的支持和改进。第五,介绍高并发框架Akka的使用方法。最后,详细介绍并行程序的调试方法。, 《实战Java高并发程序设计》内容丰富,实例典型,实用性强,适合有一定...
  • 半同步半异步模式

    千次阅读 2014-07-03 10:16:36
    这篇文字介绍了半同步半异步模式,这个模式运用在复杂的并行系统中,把同步和异步I/O模型集成在一起,既保持了编程简单又保证了执行的效率。这个模式中,高层使用同步I/O模型,简化编程。低层使用异步I/

    半同步半异步模式
    一个架构模式,清晰的结构,高效并发的I/O

    译者:

    英文原文: http://www.cs.wustl.edu/~schmidt/PDF/HS-HA.pdf

    摘要
    这篇文字介绍了半同步半异步模式,这个模式运用在复杂的并行系统中,把同步和异步I/O模型集成在一起,既保持了编程简单又保证了执行的效率。这个模式中,高层使用同步I/O模型,简化编程。低层使用异步I/O模型,高效执行。各种操作系统和其它复杂的并行系统中广泛使用这个模式,使用这个模式的操作系统有:UNIX, Mach,Windows NT,and VMS。

    1 意图
    在系统中分离了同步I/O和异步I/O的两个过程,既简化了并行程序实现的复杂,又不会影响执行的效率。

    2 动机
    如图一所示,为了说明半同步半异步模式,我们来考虑一个软件架构,BSD UNIX[1]的网络子系统。BSD UNIX的内核负责协调异步通信设备(如:网络适配器、远程终端)和应用程序之间的I/O行为。数据包随时到达设备,产生硬件中断,然后由中断处理例程把数据交给操作系统内核。这些中断处理例程接收数据,触发上层的网络协议处理(如 IP,TCP和UDP)。应用数据包在套接口层排队。操作系统把这些数据包分发给每个用户进程。用户进程使用系统调用read,以同步的方式接收套接口层的数据。用户进程可以在任意时刻调用read,当数据没有到达的时候,进程将一直阻塞等待。

    在这个体系中,操作系统内核响应设备的中断,执行异步的I/O。而用户级的应用程序进行同步的I/O。这正是“半同步半异步”这个名字的由来,这个结构满足下面的两个需要:

    编程实现简单。异步I/O模型中,中断随时触发输入和输出操作,编程复杂。使用异步I/O模型,当中断处理例程拥有线程控制权时,会产生非常麻烦的时序和竟争问题。而且,使用中断机制的程序要求额外的数据结构,这个数据结构用于在异步事件发生的时候保存进程上下文状态。并且,程序执行的时候,外部的事件会在不固定的时间发生,程序不容易调试。

    与其相比,使用同步I/O模型的时候,I/O操作在确定的点发生,编程实现要容易的多。此外,同步I/O操作的程序会阻塞等待I/O操作的完成。进程运行上下文的活动记录自动在运行栈中保存,不必使用独立的数据结构。因此,为了让编程简单,有强烈的理由使用同步I/O模型。

    程序执行高效。在中断驱动的设备上,异步I/O模型运用带来了高效率。异步I/O让通信和计算同时进行。并且,因为程序运行状态的数据量相对较小,上下文切换的消耗被最小化[2]。因此,为了提高运行的性能,也有强烈理由使用异步I/O模型。

    与其相比,如果每种资源的事件(例如网卡,终端和计时器)占用一个独立的活动对象(进程或线程),一个完全同步I/O模型效率会低。每个活动对象包含多个资源(例如栈,寄存器),每种资源都会让它阻塞,等待资源事件的发生。在创建,调度,分发和终止这些独立的活动对象,会消耗更多的时间和空间。

    3 方案
        编程简单和高效率执行是矛盾的,半同步半异步模式目的正是为了解决这个矛盾。这个模式集成了同步和异步两种I/O模式,结构清晰,效率高。在这个模式中,上层的任务(如:数据库查询,文件传输)使用同步I/O模型,简化了编写并行程序的难度。而底层的任务(如网络控制器的中断处理)使用异步I/O模型,提供了执行效率。一般情况下,上层的任务要比下层的任务多,使用一个简单的层次实现异步处理的复杂性,可以对外隐藏异步处理的细节。另外,同步层次和异步层次任务间的通信使用一个队列来协调。   

    4 应用 
    半同步半异步模式在下面的场景中使用。

    × 一个系统中的进程有下面的特征:
    系统必须响应和处理外部异步发生的事件,
    如果为每一个外部资源的事件分派一个独立的线程同步处理I/O,效率很低。
    如果上层的任务以同步方式处理I/O,实现起来简单。

    × 一个或多个任务必须在单独的控制线程中执行,其它任务可以在多线程中执行。
    例如,X Window和Sun RPC 的库函数许多是不可重入的。多个控制线程不能安全地同时调用这些函数。然而,为了使多个CPU提高服务的质量,有必要使用并行,不同的线程同时执行批量数据的传输或数据库的查询。使用半同步半异步模式,可以在多线程中分离出单独的线程。在不改变现有代码的情况下,这个分离可以让不可重入的函数在并行环境正确执行。

    5 结构和组成单元
    图二显示了半同步半异步模式的组成结构。这些组成单元如下描述

    ×同步任务层(用户级的进程)
    本层的任务完成上层的I/O操作,使用同步I/O模型,通过队列层的队列中传输数据。和异步层不同,同步层的任务使用活动对象[3]执行,这些活动对象有自己运行栈和寄存器状态。当执行同步I/O的时候,他们会被阻塞/睡眠。

    ×队列层(套接口层)
    这个层在同步任务层和异步任务层之间,提供了同步控制和缓存的功能。异步任务的I/O事件被缓存到消息队列中,同步任务层在队列中提取这些事件(相反方向亦然)。

    ×异步任务层
    处理低层的事件,这些事件由多个外部的事件源产生(例如网卡,终端)。和异步任务不同,此层的实体是被动对象,没有自己的运行栈,要求不能被阻塞。

    ×外部事件源(网络接口)
    外部设备产生事件,产生的事件先被异步任务层接收和处理。

    6 协作
    图三展现了一个动态的过程:当外部事件到达后,半同步半异步模式的各个组成单元协作和处理。把协作的过程分成下面三个阶段:

    ×异步阶段。通过中断机制或异步事件通知,外部的事件源和异步任务层完成交互。

    ×排队阶段。队列层的队列提供了一个同步控制机制,响应输入事件,缓存同步层和异步层之间的消息,

    ×同步阶段。同步任务层在队列层提取消息。注意,同步层和异步层专递数据的协议是独立的,和队列层具体处理通信的方式无关。
    在图三中,同步层和异步层之间的通信使用生产者/消费者模型。理解这个模型的关键是:完成同步任务的是活动对象。他们可以在任意时刻阻塞调用read或在 write。如果数据没有准备好,这些活动对象可以一直等待。相反的,异步任务层的实体是被动对象。他们不能被阻塞。这些对象被通知或外部对象触发。

    7 结果
    半同步半异步模式有下面的优点

    ×上层的任务被简化,这是因为不需要再面对底层的异步I/O。复杂的并发控制,中断处理和计时操作都委托给异步任务层。异步层负责处理底层的细节,如,异步系统编程的中断处理。异步任务层管理与硬件相关的组件间(如DMA,内存管理,设备寄存器)的交互。

    ×不同层可以使用不同的同步策略。每一层不必使用相同的并行控制方式。例如,在单线程的BSD UNIX内核中,异步任务层使用低级的机构(如修改CPU的中断级别)。与此不同,用户级的进程使用高级的同步机构(如使用信号量,消息队列,条件变量,记录锁)。

    ×层间的通信被限制在单独的一点,因为所有的交互使用队列层协调。队列层对两层之间的消息进行缓存。如果直接通信,同步和异步任务层直接访问对方的内存,就必须使用复杂的锁和时序控制。

    ×在多处理器环境中提高了性能。使用同步的I/O可以简化编程和提高性能。例如,长时间的数据传输(如从数据库中加载一个大的医学图象)使用同步I/O效率更高。因为一个处理器单独为一个线程使用,可以更有效的使用CPU的指令和数据的缓存。

    半同步半异步模式有下面的缺点

    × 跨边界导致的性能消耗,这是因为同步控制,数据拷贝和上下文切换会过度地消耗资源。在同步和异步任务层之间使用队列层传送数据的时候,这种消耗往往会发生。特别是,许多使用半同步半异步模式的操作系统,把队列层放到用户和内核域的边界上。到跨越这个边界的时候,往往会有明显的性能消耗。例如,BSD UNIX的套接口层,在很大比例上造成了TCP/IP网络的过载[4]。

    ×上层任务缺少异步I/O的实现。依赖与系统接口的设计,可能导致上层无法直觉使用低层的异步I/O设备。因此,如果外部的设备支持异步的重叠的I/O方式,系统的I/O结构会防碍应用程序高效的使用。

    8 实现
    这一节描述如何实现半同步半异步模式,系统中分成了同步任务层和异步任务层,两层之间使用队列层通信。
       
    8.1 找到消耗时间的长时任务,使用同步I/O实现他们。
    使用同步I/O方式,可以让系统任务的实现简单化,而系统中经常有会时间长的任务,如执行大量流数据碰[5]传输,或者是等待服务器响应的数据查询。

    使用活动对象[3]模型实现这些长时任务。活动对象拥有自己的运行栈和寄存器状态,在执行同步I/O的时候可以被阻塞。实现活动对象结构,要求一个控制线程的切换机制,需要一个地方存放和恢复线程的状态(如寄存器的值,栈指针),这些功能足够实现一个非抢占的,没有内存保护的线程机构。“用户级线程”包一般实现了此类的功能(译者:操作系统都实现了这个功能)。
    然而,在一个要求健壮的多任务系统中,要使用进程或线程的方式实现活动对象,需要更多的功能。这种情况下,每种线程需要自己的线程(或进程)空间,这些空间被处理器的内存管理单元(MMU)管理。当线程(或进程)切换的时候,新的地址空间信息需要加载到MMU中。切换时还需要清空高速缓存,特别是高速缓存使用虚拟地址的情况下。除了地址空间,一个操作系统进程还可能包含一个“用户ID”。这个标识告诉操作系统这个进程的访问权限和占用的系统资源。
    为了防止一个单独的线程(或进程)永久的占用系统,要有抢占的机制。经常使用计时器实现,计时器周期性的产生时钟中断。在中断处理期间,操作系统检查当前的进程是否应该被抢占。如果应该被抢占,就保存当前进程的状态,加载下一个进程的状态运行。
          
    8.2 找到短时任务,使用异步I/O实现
    系统中的一些任务不能阻塞过长的时间。这些任务一般和外界事件完成一个短期的交互过程(如图形用户界面或中断驱动的网络接口器),为了提高效率和保证响应速度,这些外部事件的处理一定不能阻塞。
    实现这样的短期任务,要使用被动对象[6]模型。被动对象使用别人的控制线程(调用者的线程或者一个独立的中断栈)。因为他们不能常时间的等待,不能被阻塞。不阻塞的主要目标是保证其响应时间(如高优先级的硬件中断,如时钟中断)。
    实现一个结构清晰的异步I/O框架,有多种方式。

    × 使用反应堆模式[6]实现多路事件的处理,反应堆模式使用一个单线程的处理循环,把多路的事件派发给多个处理者。这个模式组合了单线程处理循环的简单性和面向对象编程提供的可扩展性。反应堆模式在一个线程(或进程)中进行顺序的消息处理,常用来消除多线程同步和加锁处理的复杂性。
    一个反应堆可以使用在同步或者异步的事件源上。但是它支持的事件处理者的行为要求是异步的。也就是说,为了不影响其它事件源的响应效率,事件处理者是不能阻塞的。

    ×实现一个多级的中断处理机构。这种机构下,当更高级别的任务(如硬中断)要求处理的时候,当前的进程可以被中断。为了防止共享的状态访问时被破坏,异步层使用的数据结构必须被保护(例如提升处理器级别或使用信号量)。

    × 例如,在一个操作系统内核中,硬件中断的服务时间很大程度上决定了对多级中断处理机构的需要。如果这个时间能够显著的减少,可以把所有的处理放到硬中断的层次上,这样就可以避免软中断的过度资源消耗。TCP/IP的实现中,就减少输入包的协议处理时间化费,让所有的包处理过程可以在两级中断机构实现。

    8.3 实现一个队列层
    队列层包含了一个同步控制点,缓存同步任务和异步任务之间交换的消息。在实现队列层的时候,要注意下面几点:

    × 并行控制。如果同步任务和异步任务的执行是并行的(如论使用多CPU还是硬件中断),为了避免争用,共享的队列的状态变化必须是连续的。因此,实现队列层的时候,经常使用并行控制机制,如信号量,互斥体和条件变量等。当消息在队列中插入或删除的时候,并行控制保证队列的内部数据结构不被破坏。

    ×层到层之间的流量控制。在队列层缓存消息,系统不能提供无限的资源。因此,必须控制同步和异步层之间传输的数据量。例如,在层到层的流控制下,避免同步层的数据量超过网络接口能够传输的极限。
    同步任务可以被阻塞。因此,可以使用下面的策略:如果其排队超过一定的量,可以让任务阻塞。当异步任务层把排队数降低到一定的水平,就可以重新唤醒同步任务继续执行。相对地,异步层地任务不能被阻塞,当处理过量地数据时,队列层要根据策略丢弃消息。这种情况下,如果使用了一个可靠的,面向连接的网络协议,发送者最终会发现传输超时,要求重新传输数据。

    ×数据拷贝消耗。一些系统(如BSD UNIX),把队列层放到了用户和内核之间的保护边界上。为了分离不同的保护域,一般使用拷贝数据的方法。然而,这增加了系统总线和内存的负担。当大数据量的消息传输的时候,这可能会降低很大的性能。
    一种减少数据拷贝的方式:分配一个专用的内存区,这个内存区被同步任务层和异步任务层共享[7]。这样,两层之间可以高效率的交换数据,不需要拷贝。例如 [8],存在一个I/O子系统,使用轮询的中断机制改进连续的I/O流处理,最小化跨边界数据传送消耗。这种方法同时提供了一个缓存管理系统,准许高效率的页影射,一个由用户进程,内核,设备使用的共享内存机构。

    9 例子代码
    这节说明两个使用半同步半异步模式的例子,这是在BSD UNIX中两个不同部分。这些例子将说明:半同步半异步模式如果让用户进程同步操作,让内核进程异步操作。第一个例子,在网络子系统中使用这个模式,在以太网上处理通过TCP/IP协议栈输入的数据。第二个例子,在文件系统上使用这个模式,在磁盘控制器上实现一个中断驱动的输出过程。

    9.1 BSD网络子系统的例子
    这个例子说明了如何把半主动半自动模式应用与read系统调用,实现同步的操作。异步地接收和处理到达网络接口的数据,同步完成read的调用。图一 说明了BSD UNIX中,这个模式的参与者和结构。关于BSD UNIX网络子系统的完整解释,请参考[9].

    9.1.1同步调用
    考虑一个用户进程,创建了一个被动模式的TCP流套接口,从连接的套接口描述子中接收TCP数据。对用户进程来说,read系统调用就是一个同步的操作,进程调用然后数据返回。当read被调用时,它进入操作系统内核,进入网络套接口的实现代码。最终,控制线程会进入soreceive函数,这个函数完成半同步部分的处理。soreceive负责把套接口队列的数据传递给用户。它必须能够处理多种类型的套接口(如数据报套接口和流套接口)。下面是简化后的样子,重点强调了同步和异步任务层之间的边界。
    /* Receive data from a socket. */
    int soreceive ( ... )
    {
        for (;;) {
            sblock (...); /* lock socket recv queue */
            /* mask off network interrupts to protect queue */
            s = splnet ();
            if (not enough data to satisfy read request) {
                sbunlock (...); /* unlock socket queue */
                /***** Note! *****
                * The following call forms the boundary
                * between the Sync and Async layers. */
                sbwait (...); /* wait for data */
                splx (s); /* drop splnet */
            }
            else
                break;
        }
        splx (s); /* drop splnet */
        /* copy data to user’s buffer at normal priority */
        uiomove (...);
        s = splnet (); /* mask off network interrupts */
        sbunlock (...); /* unlock socket queue */
        splx (s); /* restore spl */
        return (error code); /* returns 0 if no error */
    }

    上面的代码展示了同步的用户进程和异步的内核进程之间的边界。用户进程可以阻塞等待数据,内核却不能被挂起,因为其它的用户进程或硬件设备需要它的服务。

    soreceive处理read的请求有多种方式,这取决于套接口的属性和当前队列中的数据。

    ×完全同步。如果用户请求的数据已经在套接口队列中,数据将被立即取出,同步地完成操作。

    ×半同步半异步。如果请求的数据还没有到达内核,内核将调用sbwait函数,让用户进程阻塞至数据到达。

    一旦sbwait让进程进入随眠状态,操作系统的调度者会立即把上下文切换到其它进程运行。但原来的用户进程看起来,read系统调用是同步执行的。当包含数据的包到达内核时,将被异步处理,见9.1.2的描述。当足够多的数据到达队列后,内核将唤醒原来的进程进行处理。

    9.1.2 异步数据接收和协议处理
    当异步数据包到达网络接口的时候,半异步部分启动。所有输入的包在中断处理例程中处理。中断处理,没有进程上下文也没有控制线程,这期间是不能睡眠(被阻塞)的。因此,一个中断处理例程必须借用调用者所在的控制线程(例如,它的运行栈和寄存器)执行。BSD UNIX 内核使用这个策略,借用发起系统调用的用户线程。

    许多中断驱动的计算机给中断分配优先级。例如,在SPARC体系中,一共有15个中断级别,最低的是Level 1 最高的是Level 15。其它的处理器有不同的级别数(例如,Motorola 68030有7个中断级别)。在BSD UNIX中,设计了与机器无关的中断级别,叫SPL级别(SPL这个词原于古老的PDP-11机器上的UNIX系统),把每个处理器特有的级别将影射到这个SPL级别上。例如,最高的网络中断级别为SPLIMP,时钟中断为SPLCLOCK,最高的系统中断级别是SPLHIGH。每一个中断级别对应一个函数名字,这个函数完成处理器对应中断级别的设置。所以,函数splimp调用后,将把所有的网络硬件中断排除在外。所有的spl*函数返回上一个处理器级别,这个值供恢复使用。

    传统的BSD UNIX版本使用两级的中断结构进行数据包的处理。硬件级关键处理在高级别(SPLIMP)上完成,较不关键的软件处理在低级别(SPLNET)上完成。这种两个级别的体系,防止软件协议处理的过度消耗对硬中断处理造成延时。两个级别的包处理体系自然分成了两部分:硬件相关的处理和软件协议处理。当一个包到达网络接口时,产生那个接口级别的中断,所有网络接口的中断优先级<=SPLIMP。操作系统处理硬件的中断,把进入的数据包交给协议层处理(如IP协议)。当硬中断的处理完成,并且没有其它的未处理完的高级别中断,较低级别的软件中断(SPLNET)开始进行剩余的协议的处理。BSD的内核被小心的设计,保证在软中断处理的过程中,如果又发生硬中断,不会造成数据丢失和缓存被破坏的情况。

    考虑一个例子,一个主机安装了AMD LANCE的以太网卡,这个设备的驱动名字叫“le”。当数据到达的时候,中断处理中lerint函数被调用。它的工作是确认和清除中断,从包中提取数据,把数据拷贝到名字为mbuf的内存缓存区。如下:
    int lerint (...)
    {
    /* perform hardware sanity checks */
    while (inbound buffers to process) {
         /* get length and clear interrupt ... */
         /* read the packet into mbufs */
         ether_input (interface, ether_type, packet);
         /* free buffer */
    }
    }

    mbuf被传递给以太函数ether_init
    int ether_input (char *intf, int etype, struct mbuf *packet)
    {
       switch (etype) {
          case ETHERTYPE_IP:
          /* schedule network interrupt */
           schednetisr (NETISR_IP);
           inq = &ipintrq;
          break;
          /* etc... */
       }
       s = splimp ();
       /* Try to insert the packet onto the IP queue. */
       if (IF_QFULL (inq)) {
          /* queue full, drop packet */
          IF_DROP (inq);
          m_freem (packet);
       }else
          /* queue packet for net interrupt */
          IF_ENQUEUE (inq, m);
          splx (s);
    }

    每一个网络协议拥有一个数据包队列(例如,IP 包队列),ether_input函数先检测应该使用哪一个网络协议,把数据包入队到正确的协议的队列中。然后,一个软中断发生,这个中断是较低的SPLNET级别。到了这里,硬件中断的处理已经完成,中断服务例程退出。

    硬中断完成后,当没有更高级别中断的时候,SPLNET级别的软中断发生。如果输入的数据包是一个IP数据包,内核将调用IP中断例程(ipintr)。在这个例程中进行IP协议的处理(如:消息头解析,包转发,分解和重组)。如果数据包确定要发给本机的进程,把数据包传递给传输层。传输层会进行更多的协议处理(如TCP协议级的重组和确认)。最终传输层把数据放到套接口队列中,调用sbwakeup,这个调用将唤醒原来的用户进程,这个进程之前在 soreceive调用中阻塞。当这些工作完成,软中断的包处理完成。

    下面的代码对ipintr的处理流程进行了说明,从tcp_input,到sowakeup,组成了同步和异步层的边界,第一个函数ipintr,处理输入的数据包。
    int ipintr (...)
    {
       int s;
       struct mbuf *m;
       /* loop, until there are no more packets */
       for (;;) {
         s = splimp ();
         IF_DEQUEUE (&ipintrq, m); /* dequeue next packet */
         splx(s);
         if (m == 0) return; /* return if no more packets */
         if (packet not for us) {
             /* route and forward packet */
         } else {
            /* packet for us... reassemble */
            /* call protocol input, which is tcp_input() */
            (*inetsw[ip_protox[ip->ip_p]].pr_input)(m, hlen);
         }
       }
    }

    在我们的例子中,要处理的是一个TCP/IP的包,inetsw函数会根据判断结果调用tcp_input函数。这个函数处理一个输入的TCP数据包。
    int tcp_input (m, iphlen)
    {
       /* lots of complicated protocol processing... */
       /* We come here to pass data up to the user */
       sbappend (&so->so_rcv, m);
       sowakeup((so), &(so)->so_rcv);
       /* ... */
    }

    函数sowakeup将唤醒在read调用中睡眠的用户进程,这个进程之前一直在等待数据包的到达。在下面一节的讨论中将会看到,这个函数组成了同步和异步层的边界。

    9.1.3 同步阶段的完成
    当数据添加到队列后,如果有一个用户进程正在睡眠中等待这个数据,sowakeup函数将被调用。
    void sowakeup (so, sb)
    {
       /* ... */
       if (a user process is asleep on this queue) {
          /***** Note! *****
          The following call forms the boundary
          between the Async and Sync layers. */
          wakeup ((caddr_t) &sb->sb_cc);
       }
    }

    当一个进程陷入睡眠后,进程会和一个“Handle”绑定在一起。要唤醒这个睡眠的进程,wakeup以这个Handle为参数。一个等待事件的线程,一般使用和这个事件相关的数据结构的地址作为Handle。在我们的例子中,套接口接收队列的地址(sb->sc_cc)作为Handle。

    如果套接口队列上没有等待数据的进程,什么也不会发生。在我们的例子中,如9.1.1的说明,原来的进程阻塞在soreceive调用上。内核将要唤醒这个进程,它循环检测是否有足够多的数据到达供read使用。如果足够的数据到达,soreceive把数据拷贝到用户的缓冲区,系统调用read将会返回。

    对应用户进程,read调用看起来就是同步的。然而,这不过是半同步半异步模式造成的幻觉。特别地,异步进程和上下文的切换,在用户进程睡眠的过程中默默地发生。注意,内核不会阻塞,会一直在干活,总有一些东西在运行,哪怕是空闲进程行。

    9.2 磁盘控制器的例子
    这个例子说明了在BSD UNIX的文件子系统中使用半主动半被动模式的情况。上面的例子说明了这个模式中,数据在网络接口卡输入通过TCP/IP的协议栈一直传递到用户进程。下面这个例子将说明如何输出数据,数据来自用户的进程,通过了BSD UNIX 的I/O子系统, 最后到达磁盘。
    访问UNIX的磁盘类的存储设备,有两种方式。一种是通过/dev下的块设备文件,另外一种是通过字符设备文件。通过块设备文件访问的时候,要通过一个软件实现的磁盘块缓存区。与此相反,通过字符设备(叫“raw”I/O)访问的时候,会绕过缓存系统直接进行I/O操作。挂接一个文件系统前,Raw I/O往往用来做完整性检查。一些用户级别的数据库,想自己实现磁盘缓存机制,也会使用raw I/O。

    9.2.1 同步调用
    如果一个进程打开一个字符设备文件(例如:/dev/rdk0a),进行一个写动作,当设备驱动真正完成写动作后才会结束。这是半同步的处理部分,多数原始磁盘设备有一个write动作的执行入口点,入口点作为一个全局I/O的例程存储在全局的cdevsw向量中。如下所示。
    /* Do a write on a device for a user process. */
    int raw_write (dev_t dev, struct uio *uio)
    {
        return physio (cdevsw[major(dev)].d_strategy,
                       (struct buf *) NULL,
                       dev, B_WRITE, minphys, uio);
    }

    这个函数同步调用了physio,physio在用户进程的请求下完成物理I/O动作,物理I/O直接从裸设备写入到用户缓存区,绕过系统的高速缓存。如下实现
    int physio (int (*strategy)(),
                struct buf *bp,
                dev_t dev,
                int flags,
                u_int (*minphys)(),
                struct uio *uio)
    {
        struct iovec *iovp;
        struct proc *p = curproc;
        int error, done, i, nobuf, s, todo;
        /* ... */
        /* read and write, from above */
        flags &= B_READ | B_WRITE;
        bp->b_flags = B_BUSY | B_PHYS | B_RAW | flags;
        /* call driver's strategy to start the transfer */
        (*strategy) (bp);
        /***** Note! *****
         The following call forms the boundary
         between the Sync and Async layers. */
         while ((bp->b_flags & B_DONE) == 0)
             /* Wait for the transfer to complete */
             tsleep ((caddr_t) bp, PRIBIO + 1, "physio", 0);
         /* ... */
    }

    这个physio例程使用一个用户缓冲区,一个设备和设备的strategy函数指针作为参数。这个例程的任务是:发起一个读或写操作,然后立即返回。因为执行用户缓冲去的指针是用户提供的,第一步必须认。一旦确认,就把缓冲区封装到一个buf的结构体中。buf结构体的标志被设置说明其是一个写还是一个读操作。同时有标志说明了这是一个raw I/O的操作。当buf的结构体设置好,就传递到strategy,这个例程调度I/O操作并返回。下一步,physio睡眠直到I/O操作完成。

    9.2.2 异步处理
    带缓存的和raw I/O的请求,都是同步的进入设备的驱动,通过strategy函数。
    void strategy (struct buf *bp)
    {
    /* ... */
    s = splbio (); /* protect the queues */
    /* sort the buffer structure into the
    driver's queue (e.g., using disksort()) */
    if (drive is busy) { splx (s); return; }
          /* flow control is here.... if the
          drive is busy the request stays in the queue */
          /* start first request on the queue */
          /* done! */
          splx (s);
          return;
    }
    strategy被设计成通用的函数,大部分设备的I/O都使用这个接口。上面的例子假定驱动一次只处理一个请求。一个设备可能在一个时间处理多个请求,在这种情况下,需要使用多个列表保存哪一个缓存区是激活的,哪一个正在等待I/O。           
              
    9.2.3 同步完成阶段。
    当磁盘控制器完成操作后,会产生中断。这将触发一个中断处理例程,这个例程联系了同步任务层和异步任务层。如下面的代码
    int intr (void *v)
    {
         struct buf *bp;
         /* get current request into "bp" */
         /***** Note! *****
          The following ties the Async layer back
          into the Sync layer. */
         biodone (bp); /* Wakeup the sleep in physio(). */
         /* start next request on queue */
         return (1); /* done */
    }

    这个中断处理函数,完成中断服务并清除硬件中断。查看驱动的状态表检测一个I/O是不是完成。一个I/O的请求使用异步buf结构描述,一旦boidone函数被调用,将通知高一级的内核软件,write请求已经完成。这会导致进程的tsleep调用返回。

    10 变化
    使用半同步半异步模式的传统方式是:来自异步任务层的输入使用“pash-driver”的I/O,来自同步任务层的输入使用“pull-driver”的I/O,处理输出使用相反的方式。在一些系统中有下面的变化。

    ×组合异步通知和同步I/O。当数据在排队层缓存后,通知同步层。UNIX的SIGIO就是实现的这种信号驱动的I/O。在这种情况下,一个信号发给上层的用户进程,然后用户进程使用read读出数据。

    ×当要求异步处理的时候新产生线程。组合异步通知和同步I/O的另外一种方式,当异步事件发生的时候产生一个新的线程。

    × 在上层任务中使用异步I/O。一些系统扩展了原来的模型,准许把传递数据的通知发给上层任务。UNIX SYSTEM V 的第4版本使用这种方法扩展了信号接口。一个缓冲区指针作为信号处理函数的参数传递。Windows NT 使用重叠I/O的方式实现了相似的结构。这种结构中,一个异步事件中包含一个重叠的IO结构,结构中包含完成事件的标识和对应的数据。

    × 底层任务实现同步的I/O。单线程的操作系统(如BSD UNIX)。通常只对上层的任务使用混合的同步/异步模型。在这些系统中,底层的任务必须严格的使用异步I/O。如果使用线程实现上下文切换,系统准许在内核中使用同步的I/O。在高性能的媒体系统中,使用一个内核线程在固定的时间轮询共享内存特定的域,使用这种轮询的中断机制,可以减少上下文切换。
    如果异步任务层拥有自己的控制线程,他可以自动运行把消息通过队列层传递给同步任务层。微内核操作系统一般使用这种设计。在微内核中使用一个独立的进程和用户进程交换数据。

    11 Known Uses
    ×The BSD UNIX networking subsystem [1] and the original System V UNIX STREAMS communication framework [12] use the Half-Sync/Half-Async pattern to structure the concurrent I/O architecture of user processes and the OS kernel. All I/O in these kernels is asynchronous and triggered by interrupts. The Queueing layer is implemented by the Socket layer in BSD and by STREAM heads in System V STREAMS. I/O for user processes is synchronous. Most UNIX applications are developed as user processes that call the synchronous higher-level read/write interfaces. This design shields developers from the complexity of asynchronous OS handled by the kernel. There are provisions for notifications (via the SIGIO signal) that asynchronously trigger synchronous I/O.
    ×The multi-threaded version of Orbix 1.3 (MT-Orbix) [13] uses several variations of the Half-Sync/Half-Async pattern to dispatch CORBA remote operations in a concurrent server. In the Asynchronous layer of MTOrbix a separate thread is associated with each HANDLE that is connected to a client. Each thread blocks synchronously readingCORBArequests from the client. When a request is received it is formatted and then enqueued at the Queueing layer. An active object thread in the Synchronous layer then wakes up, dequeues the request, and processes it to completion by performing an upcall on the CORBA object implementation.
    ×The Motorola Iridium system uses the Half-Sync/Half-Async pattern in an application-level Gateway that routes messages between satellites and ground control stations [14]. The Iridium Gateway implements the Half-Sync/Half-Async pattern with the ADAPTIVE Service eXecutive (ASX) framework [15]. The Reactor [6] class category from the ASX framework implements an object-oriented demultiplexing and dispatching mechanism that handles events asynchronously. The ASX Message Queue class implements the Queueing layer, and the ASX Task class implements active objects in the Synchronous task layer.
    ×The Conduit communication framework [16] from the Choices OS project [17] implements an object-oriented version of the Half-Sync/Half-Async pattern. User processes are synchronous active objects, an Adapter Conduit serves as the Queueing layer, and the Conduit micro-kernel operates asynchronously. 

    12 Related Patterns
    ×The Synchronous task layer uses the Active Object pattern[3].(这个模式,我也已经翻译了)
    ×The Asynchronous task layer may use the Reactor pattern [6] to demultiplex events from multiple sources of events.
    ×The Queueing layer provides a Facade [18] that simplifies the interface to the Asynchronous task layer of the system.
    ×The Queueing layer is also a Mediator [18] that coordinates the exchange of data between the Asynchronous and Synchronous task layers.


    Acknowledgements
    We would like to thank Lorrie Cranor and Paul McKenney for comments and suggestions for improving this paper.

    References

    [1] S. J. Leffler,M.McKusick,M. Karels, and J.Quarterman, The Design and Implementation of the 4.3BSD UNIX Operating System. Addison-Wesley, 1989.

    [2] D. C. Schmidt and T. Suda, "Measuring the Performance of Parallel Message-based Process Architectures," in Proceedings of the Conference on Computer Communications (INFOCOM),(Boston, MA), pp. 624-633, IEEE, April 1995.

    [3] R. G. Lavender and D. C. Schmidt, "Active Object: an Object Behavioral Pattern for Concurrent Programming," in Proceedings of the 2nd Annual Conference on the Pattern Languages of Programs, (Monticello, Illinois), pp. 1-7, September 1995.

    [4] N. C. Hutchinson and L. L. Peterson, "The x-kernel: An Architecture for ImplementingNetwork Protocols," IEEE Transactions on Software Engineering, vol. 17, pp. 64-76, January 1991.

    [5] D. C. Schmidt, T. H. Harrison, and E. Al-Shaer, "Object-Oriented Components for High-speed Network Programming,"in Proceedings of the 1st Conference on Object-Oriented Technologies and Systems, (Monterey, CA),USENIX, June 1995.

    [6] D. C. Schmidt, "Reactor: An Object Behavioral Pattern for Concurrent Event Demultiplexing and Event Handler Dispatching," in Pattern Languages of Program Design (J. O.Coplien and D. C. Schmidt, eds.), Reading, MA: Addison-Wesley, 1995.

    [7] P. Druschel and L. L. Peterson, "Fbufs: A High-Bandwidth Cross-Domain Transfer Facility," in Proceedings of the 14th Symposium on Operating System Principles (SOSP), Dec.1993.

    [8] C. Cranor and G. Parulkar, Design of Universal Continuous Media I/O, in Proceedings of the 5th InternationalWorkshop on Network and Operating Systems Support for Digital Audio and Video (NOSSDAV (Durham, New Hampshire),pp. 83-86, Apr. 1995.

    [9] W. R. Stevens, TCP/IP Illustrated, Volume 2. Reading, Massachusetts:AddisonWesley, 1993.

    [10] H. Custer, Inside Windows NT. Redmond, Washington: MicrosoftPress, 1993.

    [11] D. L. Black, "Scheduling Support for Concurrency and Parallelism in the Mach Operating System, IEEE Computer,vol. 23, pp. 23-33,May 1990.

    [12] D. Ritchie, A Stream Input-Output System,"AT&TBell Labs Technical Journal, vol. 63, pp. 311-314,Oct. 1984.

    [13] C. Horn, "The Orbix Architecture," tech. rep., IONA Technologies,August 1993.

    [14] D. C. Schmidt, A Family of Design Patterns for Applicationlevel Gateways," The Theory and Practice of Object Systems (Special Issue on Patterns and Pattern Languages), vol. 2, no. 1, 1996.

    [15] D. C. Schmidt, "ACE: an Object-Oriented Framework for Developing Distributed Applications, Proceedings of the 6th USENIX C++ Technical Conference, (Cambridge, Massachusetts),USENIX Association, April 1994.

    [16] J. M. Zweig, "The Conduit: a Communication Abstraction in C++," in Proceedings of the 2nd USENIX C++ Conference,pp. 191-203,USENIX Association, April 1990.

    [17] R. Campbell, N. Islam, D. Raila, and P. Madany, "Designing and Implementing Choices: an Object-Oriented System in C++," Communications of the ACM, vol. 36, pp. 117-126,Sept. 1993.

    [18] E. Gamma, R. Helm, R. Johnson, and J. Vlissides, Design Patterns: Elements of Reusable Object-Oriented Software.Reading,MA: Addison-Wesley, 1995.
    展开全文
  • 资源名称:神经网络算法与实现基于Java语言 PDF内容简介:人工神经网络是由众多连接权值可调的神经元连接而成,具有大规模并行处理、分布式信息存储、良好的自组织自学习能力等特点,能够完成模式识别、机器学习以及...
  • 利用HQL语言以及Hadoop分布式文件系统(HDFS)和MapReduce编程模式对海量搜索日志进行分析处理, 对用户搜索行为进行了分析研究。对用户搜索行为中的查询热点主题、用户点击数和URL排名、查询会话的分析结果对于搜索...
  • 其次,介绍了 TMS320C6678 的硬件结构、软件编程结构、核间通信模型、并行调度方案以及多核加载模式,为后面 x264 代码的并行与优化以及压缩平台上电自起奠定了基础。然后,对 H.264 图像压缩标准以及并行算法相关...
  • 针对最小二乘支持向量机处理大规模数据集耗时长且受内存限制的特点,将局部多模型方法与Map-Reduce编程模式相结合,提出一种并行最小二乘支持向量机回归模型。模型由两组MapReduce过程组成,首先按照输入样本集对...
  • 高带宽模式下,对于12位线性或组合HDR数据类型,并行时钟最大为116MHz。 嵌入式控制通道在UART、I²C和混合UART/I²C模式下工作在9.6kbps至1Mbps,允许设置串行器、解串器和摄像寄存器独立于视频时钟。 为驱动较长...
  • 1.4.4并行编程14 1.4.5异步编程14 1.5.NETFramework类15 1.6名称空间15 1.7用C#创建.NET应用程序16 1.7.1创建ASP.NET应用程序16 1.7.2使用WPF17 1.7.3WindowsStore应用程序18 1.7.4Windows服务18 1.7.5WCF18 1.7.6...
  • 现代:它实现了异步编程、使用结构的无复制模式和容器的资源调控等现代范例。 性能: 通过各种功能(如硬件内部函数、分层编译和 Span)来提供高性能。 跨环境一致:在多个操作系统和体系结构(包括 x64、x86 和 ARM...
  • 研究了GPU的体系结构及CUDA的编程模式,改进了基于CPU的希尔加解密方法,使用多个线程将计算中耗时的矩阵相乘部分改造成SIMD模式,并分析了线程块内线程数对加速比的影响。实验结果表明,基于GPU的并行矩阵相乘的...

空空如也

空空如也

1 2 3 4
收藏数 70
精华内容 28
关键字:

并行编程模式pdf