1.视频和视频帧:Intel GPU(核显)的编解码故事
2.认识OpenCL和它的朋友们
3.Ubuntu完全卸载opencv
4.什么是统一建模语言?
视频和视频帧:Intel GPU(核显)的编解码故事
一般提及基于“显卡或多媒体处理芯片对视频进行解码”为硬解码,本文将探讨如何利用Intel的核显,即集成GPU实现硬解码。提及QSV,全称为Quick Sync Video,Intel在年发布Sandy Bridge CPU时,hdfs源码一同推出了这项基于核显进行多媒体处理,包括视频编解码的技术。集成核显,官方称HD Graphics,最早在Sandy Bridge前一代制程已推出,但性能提升及充分发挥在Sandy Bridge时期。Haswell及后续制程发布更高级的Iris架构。最近Intel宣布将开发独立显卡,核显发展具体走向未知。
接手QSV项目时,预期会有很多相关资料,实则相反。因此,将记录自己学习过程。
本文将介绍:
I. Intel的核显(集成GPU):
了解核显很有必要,几个月前,作者对CPU的认识还停留在“南北桥”架构。以下内容若有不准确之处,欢迎指正。
查看Gen CPU结构图,首先看CPU核心部分。在整块CPU芯片中,核显占比不小,算力不容小觑。在没有独立显卡的笔记本上,可以运行大量大型游戏,虽偶有卡顿、掉帧情况,整体表现已相对不错。
接下来,看官方给出的GPU内部结构图。GPU内部远比图上所示复杂,图中介绍的仅为部分Subslice芯片结构。GPU分为Slice部分和Un-Slice部分,Slice部分已介绍,接下来介绍Un-Slice部分。
作者找到了一张图,展示了在MFF上进行视频处理的流程:1) 首先在MFX/VDBOX模块上进行编解码;2) 接着送到VQE/VEBOX上做图像增强和矫正处理;3) 然后送到SFC上做scale和transcode;4) 最后送出到显示屏上展示。是否完全正确,作者这里做个记录。
推荐知乎文章《转》Intel Gen8/Gen9核芯显卡微架构详细剖析,深入浅出,关于thread dispatch的说明即出自该文。
最后,总结Intel集成GPU/核显结构图。
注意,这是skylake架构下的GT2/GT3/GT4 GPU结构图,X数字越大,集成的Slice和Unslice芯片更多,能力越强,价格也更高。
II. Quick Sync Video(QSV)技术:
QSV是Intel推出的将视频处理任务直接送到GPU上进行专门负责视频处理的硬件模块处理的软件技术。与CPU或通用GPU上的放映厅源码视频编码不同,QSV是处理器芯片上的专用硬件核心,这使得视频处理更为高效。
要了解QSV如何驱动GPU的MFF,首先看官方Intel® Video and Audio for Linux上的图。在介绍QSV之前,提及Intel在FFmpeg上提供的插件,包括ffmpeg-qsv、ffmpeg-vaapi和ffmpeg-ocl。详细描述如下:
· FFmpeg-vaapi提供基于低级VAAPI接口的硬件加速,在VA API标准下在Intel GPU上执行高性能视频编解码器、视频处理和转码功能。
· FFmpeg-qsv提供基于Intel GPU的硬件加速,基于Intel Media SDK提供高性能视频编解码器、视频处理和转码功能。
· FFmpeg-ocl提供基于工业标准OpenCL在CPU/GPU上的硬件加速,主要用于加速视频处理过滤器。
接下来,介绍QSV在ffmpeg2.8及以上版本的支持,经过MSDK、LibVA、UMD和LibDRM。分层进行分析:
· MSDK:Intel的媒体开发库,支持多种图形平台,实现通用功能,可用于数字视频的预处理、编解码和不同编码格式的转换。源码地址为Intel® Media SDK,在Linux平台上编译使用。
· VA-API:Video Acceleration API,提供类unix平台的视频硬件加速开源库和标准。Intel源码地址在Intel-vaapi-driver Project,在Linux平台上使用。
· UMD:User Mode Driver的缩写,指VA-API Driver。Intel提供了两个工具:intel-vaapi-driver 和 intel-media-driver,推荐使用后者。
· LibDRM:Direct Rendering Manager,解决多个程序协同使用Video Card资源问题,提供一组API访问GPU。与VA-API,LibDRM是一套通用的Linux/Unix解决方案。
· Linux Kernel:Intel的Kernel是i driver,描述了libDRM和Kernel Driver之间的关系。
至此,整个关系图较为清晰。
III. FFMPEG+QSV解码:
QSV硬解的任务主要包括:
关于3-4步操作的详细实现,底层库会帮助完成。但作为一个优秀的工程师,研究FFMPEG源码依然十分重要。接下来,介绍如何使用FFmpeg API中的h_qsv解码器插件。
提及FFmpeg命令行使用方法,推荐阅读官方资料《QuickSync》或《Intel_FFmpeg_plugins》。
关于示例代码,作者曾遇到许多坑,总结为:多数中文博客不可靠,官方demo最可信。官方代码提供了两份可用:qsvdec.c和hw_decode.c。高德源码包作者最早使用的是第一段代码,核心部分如下:
然而,这段代码存在问题。测试发现,对于赛扬系列一款CPU,在p视频上MSDK达到fps,理论上h_qsv平台上限也应为fps,但实际测试不到fps。排查后发现是av_hwframe_transfer_data()性能较弱。
最终,与Intel一起解决了性能问题。那么,性能提升方案为何是GPU-COPY技术做Memory-Mapping?
解释GPU和CPU渲染图像的过程,包括坐标系转化、纹理叠加等,仅需了解两点:
后者的数据组织方式能充分利用GPU的并行特性,加速图像处理、渲染。尽管存在一些纹理叠加的技术难题,但性能提升足以补偿。
接下来,解释Memory-Mapping:从Intel CPU架构图中可见,GPU和CPU位于同一芯片上,各自寄存器/缓存区有限,视频数据主要存储在内存上。GPU和CPU的数据组织方式不同,同一帧数据存于内存同一位置,数据格式不同,因此需要做Memory-Mapping。Memory-Mapping相较于Memory-Copy,减少了数据从内存区域A移动到区域B的操作,已经是优化。进一步优化:GPU完成Memory-Mapping以及数据从GPU到内存和CPU的操作。
在av_hwframe_transfer_data()内部,Memory-Mapping由CPU完成,性能受限于CPU,只能并行。修改后,整体性能从不到fps提升至fps,虽然与理想fps仍有差距,但满足性能需求。
据悉,Intel将在FFmpeg 4.3开源出这个解决方案。
写在后面:
了解GPU底层对应用开发人员帮助不大,毕竟了解芯片布线的重新设计、制程工艺提升、GPU-COPY技术的数据I/O提升等,也不能做什么。最终,芯片架构是芯片工程师的事,底层逻辑实现是嵌入式工程师的事。应用开发人员无法做出实质贡献,但作为知识库扩充或休闲阅读,了解也无妨。
希望有机会接触CUDA的编解码,深入学习N卡设计。
感谢因《视频和帧》系列文章结识的朋友,热心指出文章描述不准确的盛隆国际源码地方。文中如有不严谨之处,欢迎指正。
认识OpenCL和它的朋友们
本文旨在深入探讨OpenCL及其关联技术,阐述它们在异构计算领域的应用与特点。
OpenCL,由Apple设计并由Khronos维护,是一款并行计算编程框架。它专为解决并行度不足、带宽较小和延迟较高的问题而设计,提供高效且灵活的并行处理能力。
在图形处理领域,OpenGL和DirectX是主导的API,分别用于3D图形渲染。OpenGL-ES是OpenGL的子集,专为移动设备和游戏主机设计。而OpenCL则专注于GPU的通用浮点运算,适用于视频转码、卷积、池化等计算任务。CUDA、Metal和DX则代表了NVIDIA、Apple和Microsoft开发的专用API,分别针对特定硬件优化。
最新动态显示,Apple正计划弃用第三方API,转而使用自家的Metal接口。同时,Khronos集团提议合并OpenGL和OpenCL进入Vulkan,使得Vulkan在图形和计算性能上将能与DirectX相抗衡。
接下来,我们将逐一介绍每个框架的核心特性和使用流程。
OpenCL框架由主机端和设备端两部分组成。主机端负责IO处理和内核程序的提交。存储器种类繁多,包括全局、局部和私有存储器。
执行流程如下:先通过clGetPlatformIDs和clGetDeviceIDs获取平台和设备信息;接着,使用clCreateContext创建上下文,管理同一平台下的多个设备;之后,根据设备创建命令队列;程序对象包含多个内核对象,通过程序编译后,内核和内存对象通过clCreateKernel、clCreateBuffer等接口创建并配置参数;内存通过clEnqueueWriteBuffer写入内核参数;执行内核使用clEnqueueNDRangeKernel或clEnqueueTask,最后使用clEnqueueReadBuffer获取运行结果;资源回收顺序为clReleaseKernel、clReleaseProgram等。
在源代码编写方面,OpenCL C语言遵循特定规则,不支持函数指针和递归,函数调用可以内联。内核函数以__kernel限定,返回值为void,参数类型分为__read_only、__write_only和__private等。矢量数据类型支持元素级运算和标量广播。
OpenCL的编译方式多样,包括分步编译、全编译、仿真编译和硬件编译等。大公网源码在开发流程中,需要提前下载并解压板机支持包(BSP),设置环境变量,通常包含c文件和cl文件。部分卡可能需要先通过仿真编译得到aocx二进制文件。接着,利用makefile编译c文件生成主机端代码,并在调试环境中运行。最终,将硬件代码加载到设备卡上执行。
值得一提的是,OpenCL代码编译依赖特定厂商的工具,如Altera的aoc编译器,现在归Intel所有,主要针对Intel FPGA。NVIDIA和IMG等厂商也提供各自的编译器,将OCL代码编译为GPU指令集。
Ubuntu完全卸载opencv
一、完全卸载opencv
为了完全卸载OpenCV,首先找到安装目录,运行以下命令:
sudo make uninstall
之后,使用rm命令删除编译安装的目录,包括include和lib文件夹。确保删除干净,避免残留文件影响系统:
sudo rm -r /usr/local/include/opencv2 /usr/local/include/opencv /usr/include/opencv
/usr/include/opencv2 /usr/local/share/opencv /usr/local/share/OpenCV /usr/share/opencv
/usr/local/bin/opencv* /usr/local/lib/libopencv
*检查是否已完全删除,运行pkg-config命令:
pkg-config opencv --libs
pkg-config opencv --modversion
清理安装残留,使用apt-get命令卸载相关依赖库:
sudo apt-get autoremove opencv-doc opencv-data libopencv-dev libopencv2.4-java
libopencv2.4-jni python-opencv libopencv-core2.4 libopencv-gpu2.4 libopencv-ts2.4
libopencv-photo2.4 libopencv-contrib2.4 libopencv-imgproc2.4 libopencv-superres2.4
libopencv-stitching2.4 libopencv-ocl2.4 libopencv-legacy2.4 libopencv-ml2.4 libopencv-
video2.4 libopencv-videostab2.4 libopencv-objdetect2.4 libopencv-calib3d2.4
二、重新安装opencv
前往OpenCV官网下载对应版本的源代码。安装依赖库,运行以下apt-get安装命令:
sudo apt-get install build-essential
sudo apt-get install cmake git libgtk2.0-dev pkg-config libavcodec-dev libavformat-dev libswscale-dev
sudo apt-get install python-dev python-numpy libtbb2 libtbb-dev libjpeg-dev libpng-dev libtiff-dev libjasper-dev libdc--dev
编译并安装OpenCV,操作如下:
cd opencv
mkdir build
cd build
cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local ..
make -j
sudo make install
安装过程可能需要一段时间,耐心等待!
三、配置环境变量
将OpenCV库加入PATH,运行以下命令:
sudo gedit /etc/ld.so.conf/opencv.conf
在打开的文件中加入/usr/loacl/lib,保存退出。
sudo ldconfig
编辑bash.bashrc文件,将以下内容添加到文件末尾:
PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/lib/pkgconfig
export PKG_CONFIG_PATH
source /etc/bash.bashrc
检查配置是否正确:
pkg-config opencv --modversion
至此,OpenCV安装完成。
四、解决错误提示
1. 若发现之前的版本未完全卸载,导致重新安装时出现相应的目录文件不可用问题,参考前文所述彻底删除OpenCV文件。
2. 在安装依赖库时,可能遇到错误提示,指出某些依赖无法满足。这通常是由于源文件过时导致的。解决方法是添加新的源文件,例如:
deb Index of /ubuntu xenial main restricted universe multiverse
deb cn.archive.ubuntu.com/u... xenial-security main restricted universe multiverse
deb cn.archive.ubuntu.com/u... xenial-updates main restricted universe multiverse
deb cn.archive.ubuntu.com/u... xenial-backports main restricted universe multiverse
然后运行sudo apt-get update进行更新即可解决。
什么是统一建模语言?
统一建模语言UML述评
邵维忠 梅宏
摘 要 最近由美国Rational公司发起并与其它十几家公司共同推出的“统一建模语言”UML在OO领域受到广泛的关注.文中首先介绍UML产生的背景及其主要内容,然后评论它对OO建模技术的积极影响以及可能存在的问题.UML是一种表达能力丰富的、强有力的建模语言;然而,目前还不能断定它将取代现有的各种面向对象的分析与设计方法.因为它只是一种建模语言,而不是一种方法;其复杂性可能成为它赢得大量用户的障碍.
关键词 面向对象,建模方法,建模语言
中图法分类号 TP
REVIEW OF THE UNIFIED MODELING LANGUAGE(UML)
SHAO Wei-Zhong and MEI Hong
(Department of Computer Science & Technology,Peking University,Beijing )
Abstract The Unified Modeling Language(UML), published by Rational Software Corporation and other UML partners, is attracting wide attention in the area of object technology. The historical background and the main contents of UML are introduced and then its significance, positive influence and some possible problems are discussed. UML is an expressive and powerful modeling language; however, it cannot be concluded that it would replace all existing object-oriented analysis and design methods. The reason is that UML is only a modeling language rather than a method, and its excessive complexity might become an obstacle to win a great number of users.
Key words object-orientation, modeling method, modeling language
1 UML的背景
由于面向对象的分析与设计(OOA/OOD)方法的重要性日益突出,人们对它的研究、开发和应用的热情也在不断升高.在年,以专著、论文或技术报告等形式提出的OOA/OOD方法或OO建模语言有近种,到年,其数量增加到种以上.各种方法的出现都对OOA/OOD技术的研究与发展作出了或多或少的新贡献.这种“百花齐放”的繁荣局面表明面向对象的方法与技术已得到广泛的认可并成为当前的主流.然而多种方法的同时流行也带来一些问题:各种OOA和OOD方法所采用的概念既有许多共同部分也有一定的差异(例如许多方法在OO基本概念基础上各自提出了一些扩充概念,字面上相同的概念其语义解释也不尽相同);在表示符号、OOA模型及文档组织等方面差别则更为明显.这种情况往往使一些新用户在进行建模方法及工具的选择时感到难以决策,也不利于彼此之间的技术交流.
鉴于这种情况,年同在美国Rational软件公司工作的G.Booch和J.Rumbaugh认为,应该把他们各自提出的方法(Booch方法〔1〕和OMT〔2〕)结合起来,形成一种统一方法.该年月他们开始了这一工作,并于年月公开发布了第一个版本,即Unified Method 0.8.年秋OOSE〔3〕的提出者I.Jacobson加入了Rational软件公司,于是也加入了这一行列.G.Booch,J.Rumbaugh和I.Jacobson共同认为,提出一种统一的建模语言有以下3个理由:第1,他们各自提出的方法在演化中已经有互相结合的趋向;第2,走向统一将带来市场方面的好处;第3,有助于改进他们各自的方法,以获得更多的学习者并解决一些以往在他们各自的方法不能很好解决的问题.
为确定一套用于分析与设计的表示符号,他们遇到了一些需要权衡的问题.一是问题范围的界定.比如;是否应包括需求规约?(回答是,应部分地包括);是否应包括可视化编程语言?(回答为“否”).二是必须在表达能力和简单性之间作出折衷.表示法过于简单将使解决问题的能力受到限制,过于复杂则将使普通的开发者不知所措.三是在他们原先的3种方法基础上进行联合,也使他们必须顾忌对原有方法的改动大小;改动过大将引起老用户的混乱,沿用原先的东西则将失去作出改进并嬴得更多新用户的机会.从UML的文献中谈到的这些问题看,UML的提出不是单纯从学术和技术的立场寻找一种最合理的方案,而是必须考虑到与公司、老用户和原先各种方法有关的一些实际背景.
不管怎样,他们作出了在这种背景下他们认为最好的权衡,于年6月和月先后发布了UML 0.9和0.版本.从此时起,“统一方法”改称为“统一建模语言” (unified modeling language).因为确切地讲,它并不是一种面向对象的建模方法,而是一种面向对象的建模语言.它只是给出一套用于建模的元素及表示符号并定义了它们的语义,而不是讲述如何进行系统建模.正如M.Fowler在专门介绍UML的著作〔4〕中指出的:“UML被称作建模语言,而不是一种方法.至少从原则上讲,大部分方法是由一种建模语言和一种过程共同组成的.其中建模语言是一种(以图形方式为主的)表示符号,用来表达人们的设计;过程则是对进行这种设计应采取哪些步骤所提出的建议.”M.Fowler的这本书是以UML1.0版本为背景写作的,G.Booch,I.Jacobson和J.Rumbaugh亲自为该书作序.这至少可以表明,该书对UML的这种总体评价是得到其缔造者认可的.
年,Rational准备向对象管理组织(Object Management Group,简称OMG)申请将UML作为一种标准建模语言.为此创立了UML伙伴组织,包括Rational本身共有家公司加入.他们推出了UML1.0版,于年1月提交到OMG作为初步的提案申请.年另有几家公司分头向OMG提交自己的建模语言提案申请.于是,UML伙伴组织把这些公司也吸收到自己的行列中来.为了反映这些新成员的意见,又对UML1.0进行了修改,于年9月1日产生了UML1.1并提交到OMG,同年月被OMG采纳.目前UML1.1是最新版本,但不是最终版本,因为还在继续进行修改.到UML1.1发布时止参加UML联合行动的有以下家公司:Rational Software,Microsoft,Hewlett-Packard,Oracle,Sterling Software,MCI Systemhouse,Unisys,ICON Computing,IntelliCorp,i-Logix,IBM,ObjectTime,Platinum Technology,Ptech,Taskon,Reich Technologies和Softeam.
2 UML内容概述
按照UML文件的说法,“统一建模语言(UML)是一种用于软件系统制品规约的、可视化的构造及建档语言,也可用于业务建模以及其它非软件系统.”UML1.1提供了6份文件,均以UML伙伴组织中家公司的名义联合印发.本节首先简略地介绍这些文件,下一节将对其中的UML表示法指南作较详细的介绍.
(1) UML概要(UML Summary):是对UML的概括介绍,包括其动机、目标、范围、历史与现状.
(2) UML语义(UML Semantics):定义了UML的语义.定义采用了形式化技术,但并不是完全形式化的规约.对语法结构给出了精确的规约,对其动态语义则是用自然语言描述的.UML的语法是一种与表示符号无关的抽象语法,它可以映射到不同的符号体系中.尽管没完全形式化,但其定义方式也颇为复杂:采用了4级元模型体系结构,文本的篇幅达到余页.在该文件的2.2节介绍了模型的4个级别,即:
① 元-元模型(meta-metamodel):元模型的基础体系结构,定义一种说明元模型的语言.
② 元模型(metamodel):元-元模型的一个实例,定义一种说明模型的语言.
③ 模型(model):元模型的一个实例,定义一种语言来描述信息领域.
④ 用户对象(user object):模型的一个实例,定义一个特定的信息领域.
对各级模型元素的定义方式是,首先给出它的抽象语法(采用UML的类图表示法描述元素之间的关系),然后给出其形式化规则(采用正文和对象约束语言),最后描述其语义(采用准确的正文).按这种方式总共定义了个元素,划分到3个部分和9个包(package)中分别加以定义.
(3) UML表示法指南(UML Notation Guide):该文件给出UML的可视化表示法,通过例子给出模型元素的图形表示符号,详见下一节.
(4) 对象约束语言规约(Object Constraint Language Specification):该文件定义并介绍了一种对象约束语言(简称OCL),其用途是用来说明一些在图形化的系统模型中不能充分表达的建模信息.它是一种形式化的语言,但容易书写和阅读.作为一种建模语言,它并不表示实现方面的问题.就是说,它是用来对模型作详细说明的,而不是可编译执行的.
(5) 用于软件工程对象过程的UML扩充(UML Extension for Objectory Process for Software Engineering):针对软件工程中的要求,定义了一些UML的扩充概念.例如,将模型分为Use Case模型、分析模型、设计模型和实现模型4种,对每一种扩充的模型概念给出其定义.它并未介绍面向对象的开发过程,也不讲在过程中如何运用UML.文件内容很短,只有5页.
(6) 用于业务建模的UML扩充(UML Extension for Business Modeling):定义了用于业务建模的一些UML扩充概念,与上一个文件相似,只是它的扩充是针对一般业务处理建模,而不是对软件工程的.该文件也很短.
3 UML表示法指南
该文件给出UML的可视化表示法,通过例子给出模型元素的图形表示符号.从系统模型这一级别上看,UML表示法由9种图构成,它们是:
静态结构图(Static Structure Diagram),其中包括类图(Class Diagram)和对象图(Object Diagram);
Use Case图 (Use Case Diagram);
顺序图(Sequence Diagram);
协作图(Collaboration Diagram);
状态图(Statechart Diagram);
活动图(Activity Diagram);
实现图(Implementation Diagram),其中包括成分图(Component Diagram)和展开图(Deployment Diagram)两种图.
尽管UML文件称“UML表示法指南定义了表示法并提供了例子”,但确切的说法应该是:该文件对建模元素的表示法给出了一般的文字描述,其图形的画法是通过例子表现的,并没有给出一般的图示.本文大部分插图是参照M.Fowler的著作〔4〕的作法从一般意义上给出的.
UML定义了一些在各种图中常用的元素,例如String(串)、Name(名)、Label(标签)、Keyword(关键词)、Expression(表达式)、Note(注释条)等,并给出它们的表示符号,例如关键词由一个被书名号括起的串表示,注释条用一个折起一角的长方形内的正文表示.在各种图中用来对一组模型元素打包的元素叫做“包”(Package),其表示法是用一个大的方框围起这组元素,并在角上用一个小框给出包的名字.
此外,UML还定义了一些称作“扩充机制”的元素.这种元素可以附加到其它模型元素之上,将原有的建模元素特化成一种语义较特殊的新变种,或者表示出它们的某些细节.这些元素可以起到对表示法进行扩充或细化的作用,它们是:
Constraint(约束):约束是模型元素之间的一种语义关系,它说明了某种条件和某些必须保持为真的命题.其表示法是在大括号{ }之间用一种工具能识别的语言(如UML提供的OCL)写出表示条件的正文串.
Comment(注释):注释是写在注释条表示符号(折起一个角的长方形)之内的正文串.所使用的语言应易于人的理解,不必考虑被工具理解.
Element Property(元素特征):用来显示模型元素的一些附带特征,如属性、关联、目标值等.其表示法是在大括号{ }内写出形式为 关键词=值 的正文串,多个串之间彼此用逗号隔开.
Stereotype(版式):用来附加到其它模型元素之上,将原有的建模元素特化成一种语义较特殊的新变种.带有版式的建模元素可看作原先建模元素的一个子类,它在属性、关系等方面与原先的元素形式相同,但用途更为具体.板式是用书名号《 》括起来的关键字表示的.上述概念的表示法如图1所示.
图1 图元素、包和扩充机制
以下分别介绍各种图以及图中用到的建模元素与表示法.
(1) 静态结构图
静态结构图包括类图(class diagram)和对象图(object diagram).“类图是静态结构模型的图形化示图.”“类图是(静态)声明的模型元素集合.”关于对象图,该文献中说道:“对象图是实例的一种图形,包括对象和数据的值,静态的对象图是类图的一个实例;它显示了在一个时间点上系统细节状态的一个快照”.该文献又指出:“对象图的用处是很有限的”,“工具没有必要支持独立形式的对象图.类图能包括对象,一个有对象而没有类的类图便是一个‘对象图’.不过这个术语对于刻画在各种方式下可能达到的特殊用法还是有用的”. 静态结构图中用到的各种建模元素的表示法如图2所示,以下分别加以介绍.
图2 静态结构图中的建模元素表示法
Class(类):类是对具有相似的结构、行为和关系的一组对象的描述.UML对类提供了3种图形表示符.第1种是细节抑制方式,只在一个方框中给出类名;第2种是分析级细节方式,在上、中、下3栏分别给出类名、属性名与类型、操作名;第3种是实现级细节方式,给出更多的细节.
Name Compartment(名字栏):定义了类符号的名字栏的书写规范.
List Compartment(列表栏):定义了类符号的属性栏和操作栏的书写规范.
Attribute(属性):规定了属性的写法,以及以下3种可见性符号:“+”表示public(公共),“#”表示protected(保护),“-”表示private(私有).
Operation(操作):规定了操作的写法,采用与属性相同的3种可见性符号.
Type vs. Implementation Class(类型与实现类):这是将版式关键词《type》或《implementation class》附加到类表示符号之上,并在属性栏和操作栏中给出属性与操作的定义细节而得到的两种较特殊的类元素.其中“类型”刻画一个对象可能采用然后又放弃的可变规则;“实现类”定义了在用一种语言实现时对象的物理数据结构与过程.以下7种表示符号都是用这种方式得到的.
Interface(接口):接口是对一个类或其它实体(诸如包这样的大单位)的对外可见操作的说明,它不说明实体的结构.其表示法很像类符号,但没有属性栏;在名字栏中加关键词《interface》,在操作栏填写接口定义.
Parameterized Class(Template)(参数化类,又称模板):它是带有一个或多个未绑定的形式参数的类,因此它定义一个类家族,将参数与一个实际值绑定便说明了其中一个类.参数化类的表示法是在类符号的右上角加一个虚线框,框内中说明各个形参的不同实现类型.
Bound Element(绑定元素):它的作用是将模板的参数与实际的值联系(绑定).其表示法是用文字说明模板的参数值表.
Utility(实用程序):以类的形式声明的一组全局变量与过程.它不是一种基本构造,而是一种编程便利设施.其表示法是在类符号的类名栏中标以关键字《utility》.
Metaclass(元类):即类的类,它的实例是类.其表示法是在类名栏中加关键词《metaclass》.
Class Pathname(类路径名):用以表示对一个类的引用.表示法是在引用这个类的地方(在其它包中)以符号“∷”指出被引用的类名.
Importing a Package(引入一个包):表明在一个包中可以引用另一个包中的类.这是一种特殊的依赖(dependency)关系.其表示法是在dependency符号(虚箭头)上旁加关键字《import》.
Object(对象):对象是类的一个特殊实例.UML给出的对象表示法是一个只有两栏的方框.名字栏填写对象(实例)名并指出它所属的类名.属性栏中给出每个属性的值.
Composite Object(组合对象):由一些紧绑在一起的部分所构成的高层对象,它是组合类(composite class)的实例.用含有两栏的方框表示,在上栏填写组合对象名并指出其类名,在下栏画出它的各个部分对象.
Association(关联):分为二元关联和多元关联,在以下的条目中分别介绍.
Binary Association(二元关联):是两个类之间的关联(包括从一个类到它自身的关联这种特殊情况).其表示法是用一条实线连接两个类符号.这条线可根据绘图时的方便画成平直的、斜的或弯曲的.也可由若干段组成.线的端点与类符号相接的地方叫作关联端点,端点附近可以注明一些有用的信息,表明关联的不同情况(稍后介绍).整个关联也可以带有一些附加信息,包括:关联名(association name),通过这样的命名表明关联的作用;关联类(association class)符号,和普通的类符号相同,但必须附着在一个关联上,用于表明关联的属性与操作.这些东西都是任选的、非强制的.
AssociationEnd(关联端点):关联端点不是独立的元素,它是关联的一部分,用于表明关联的一些细节内容.一部分细节内容通过在关联端点旁边附加一些字符或图形来表示,包括多重性(multiplicity)、有序性(ordering)、限制(qualifier)、角色名(rolename)、可变性(changeability)、可见性(visibility).另一些细节是通过关联线端点的不同形状来表示的,包括:开放形的箭头表示可导航性(navigability),即表示从关联一端的对象实例能够找到另一端与它关联的对象实例;空心的菱形箭头表示聚合(aggregation),即表示关联一端的对象实例是另一端对象实例的组成部分;实心的菱形箭头表示强形式的聚合关系,称作组装(composition).
Multiplicity(多重性):在关联端点上标注数字(表示具体的数量)或“*”号(表示多个),以表明本端有多少个对象实例与另一端的对象实例相关联.
Qualifier(限制),在关联的一端与类符号相接口的地方画一个矩形框,框中给出一些属性值指明关联另一端的对象符合什么条件才有资格与本端的对象关联,它是关联的一部分,而不是类的一部分.
Association Class(关联类),用于表明一个关联带有类的特征(包括属性和操作),用普通的类符号表示,附着在关联线上.
N-Ary Association(多元关联),3个以上的类之间的关联.其表示法是从一个菱形向各个相关联的类符号画出连接线.
Composition(组装)按UML的说法,composition是aggregation的形式之一,它表示整体对部分有很强的拥有关系和相同的生存时间.其表示法是在关联线的端点加一个实心的菱形箭头.
Link(链),链是关联的一个实例,表明两个对象之间的联系.其表示法是在两个对象实例之间画一条直线.
Generalization(一般化):“是较为一般的元素和与之完全一致而又增加了更多信息的较为特殊元素之间的分类学关系.” 此概念和大部分OO技术文献中所讲的“继承关系”或“一般特殊关系”基本相同,不过,UML的generalization除用于表示类之间的关系外还用于包、Use Case和其它元素.表示法有两种方式.一种是共享方式,在一般元素的符号旁边画一个三角形,从三角形的底边引出一条连线,而这条连接有若干分枝,分别连向各个特殊元素;另一种是分散式,在一般元素的符号旁边画多个三角形,每个三角形的底边画出引向一个特殊元素的连线.在连线旁边可以加一个文字标注,叫做discriminator(鉴别器),标明是按什么进行分类的.
Dependency(依赖):UML对dependency的语义是这样定义的:“指出两个(或多个)模型元素之间的语义关系.其涵义只涉及这些元素本身而不涉及他们的实例.它指出在这种依赖中对目标元素的一个改变可能需要对源元素的一个改变.”依赖有以下几种:
trace-Trace:在不同的表意层次上表示同一概念的两个元素之间的一种历史连接.
refine-Refinement:两个有映射(未必完全)关系的元素之间的历史或衍生连接.
use-Usage:为了一个元素的正确实现或功能履行需要另一个元素出现.
bind-Binding:将模板参数绑定到一个实际的值,以创建一个非参数化元素.
依赖的表示法是在两个模型元素之间画一条带箭头的虚线,旁边可以标明该依赖关系属于以上哪一种,也可加一个名字.UML表示法指南在介绍dependency时没有谈到它与message(消息)的概念有什么联系和区别.UML的“消息”、“消息流”等概念分别用于顺序图和协作图(详见后文),而不用于类图.但是M.Fowler在文献〔4〕中作了这样的解释:“对类而言,dependency可以为如下几种理由而存在:一个类向其它类发送消息;一个类以其它类作为其数据的一部分;一个类提及其它类作为对一个操作的参数.”
Derived Element(派生元素):派生元素是可以从其它元素计算出来的元素.尽管它没有增加语义信息,但是有了它可以更清楚或者更有利于设计.其表示法是在派生元素的名字前加一条斜线“/”.
(2) Use Case图
“use case图用于表现活动者与use case之间的关系.”“use case模型表现一个系统或一个类对于系统外部的交互者的功能.”UML定义了如下几种构成use case图的元素(如图3).
图3 Use Case图
Use Case:一个use case是一个系统或一个类提供的紧凑的功能单元,它是由系统与一个或多个外部交互者(即活动者)之间交换的消息序列以及系统执行的活动共同体现的.
Actor(活动者):活动者是直接与系统交互的外部对象所扮演的角色.
Use Case Relationship(use case关系),包括如下3种关系:communicates(通信),这是活动者与use case之间仅有的关系,是活动者对use case的参与;extends(延伸),从use case A到use case B的延伸关系表明B的实例(在延伸说明的特殊条件下)可能包含了在A中说明的行为;uses(使用):从A到B的使用关系表明A的实例也包括了在B中说明的行为.
(3) 顺序图
UML给出了两种形式的交互图(Interaction Diagram),一种叫顺序图,另一种叫协作图.它们基于相同的基本信息但强调不同的方面.顺序图(Sequence Diagram)展示按时间顺序排列出来的交互.特别是,它展示对象在其“生命线”上参加的交互和它们按时间顺序交换的消息.它不展示对象之间的关系.顺序图所表示的交互是一组在对象之间为产生所要求的操作或结果而进行合作时所交换的一组消息.顺序图有简单形式和详细形式两种画法,后一种画法与OOSE〔3〕等著作介绍的交互图大体一致——在水平方向展示各个参加交互的对象,垂直方向表示时间;整个平面显示各个对象之间进行交互的时间及空间关系,顺序图如图4所示.用于顺序图的建模元素有:
图4 顺序图
Object Lifeline(对象生命线):一条垂直的虚线,用于展示对象在从创建到撤消的时间范围内所扮演的角色.
Activation(活动期):展示对象直接地或通过其下级过程执行一个活动的时间段.
Message(消息):消息是对象之间的一次通信,用于传送信息并期望发生某种活动.消息的接收是一种事件.
Transition Time(过渡时间):消息发送或接收所用的时间.二者可能相同也可能不同.
(4) 协作图
协作图(Collaboration Diagram)是UML所说的另一种交互图,它表示在一些对象之间组织的操作和它们之间的链.与顺序图不同的是,协作图表示的是对象角色之间的关系,而不表示时间顺序.协作图描绘了在特定上下文中一组相关对象之间的协作,以及这组对象为产生所要求的操作或结果而进行协作时所交换的一组消息.协作图的图形表示以对象为结点,结点之间既有表示消息的箭头连线,也有表示关联的连线.消息连线有3种,分别表示调用、控制流和异步3种不同的消息,但仍有一些不能表示的情况,如阻塞(balking)和超时(time out)等,需要用一些进一步扩充的表示符号.协作图中使用的关联符号也包括多种不同的端点情况,如qualifier和composition等等.协作图如图5所示.
图5 协作图
UML表示法指南为协作图定义的概念或建模元素有:Collaboration(协作)、Collaboration Content(协作内容)、Interaction(交互)、Pattern Structure(模式结构)、Collaboration Role(协作角色)、Multiobject(多对象)、Active Object(主动对象)、Message Flows(消息流)、Creation/Destruction Markers(创建/折构标记),这里不再一一介绍.
(5) 状态图
状态图(Statechart Diagram)在UML中也称作状态机,它表现一个对象或一个交互在整个生存期内接受剌激时的状态序列以及它的反应与活动.它附属于一个类或一个方法.建立状态图所用的建模元素有:State(状态)、Composite State(复合状态)、Substate(子状态)、Event(事件)、Simple Transition(简单转换)、Complex Transition(复杂转换)、Nested State(嵌套状态)、Sending Message(发送消息)、Internal Transition(内部转换)等.状态图及其有关元素的表示法和现有的大部分OOA/OOD方法大同小异,这些不再详述.
(6) 活动图
活动图(Activity Diagram)是状态图的变种,它的状态表示操作所执行的活动(activity),其转换(transition)是由操作的完成而触发的.它表示了一个过程本身的状态机,过程是对类中一个操作的实现.构成活动图的元素有:Action State(活动状态)、Decision(判断)、Swimlane(泳道,在图中画出来就象游泳池中的泳道,把各个活动组放在不同的泳道中以便更加清晰)、Action-Object Flow Relationship(活动-对象流关系,表示一个活动与有关对象之间的消息和输入/输出关系)、Control Icon(控制图符,表示信号的发送与接收)等.活动图如图6所示.
图6 活动图
(7) 实现图
实现图(Implementation Diagram)表现实现方面的问题,包括源代码结构和运行时的实现结构.实现图分为两种,一种是表示代码自身结构的成分图,另一种是表示运行时系统结构的展开图.