Conner's profile☆ Conner Wang ☆PhotosBlogListsMore ![]() | Help |
|
|
October 02 多处理器环境下不出错而单处理器环境下却出错的多线程程序多线程程序比单线程程序要考虑的东西要多的多,如临界区、竞争、死锁、资源的维护等等。今天我写程序的时候就犯了一个低级的错误,从而导致我的程序在多CPU环境下可以运行而在单CPU环境下却出问题。 程序是用VC写的,共有两个线程:一个是GUI线程,一个是数据处理线程。处理线程会产生日志信息,日志信息会经过两种方式被处理:1. 通过发消息从而在GUI界面里增量显示;2. 在处理线程中将日志信息增量写入日志文件。 我的日志信息是一个CString,它是在堆里动态分配的。我最初的程序是将日志信息的地址发给GUI线程,GUI线程显示完毕后释放这部分内存。后来我又加上了日志写入文件这一功能,就是日志信息在GUI界面显示完毕后还会在处理进程中写入日志文件。 由于我的开发环境是多核环境,一开始并没有什么问题,但当我将程序运行在单核机器上时,有时会出问题,说是某个引用的地址0x00000000无效。经过调试我才发现问题出在内存释放这一部分:在我的多核系统中,日志信息在两个线程中同时被使用,由于GUI进程处理的稍慢,所以当它释放内存时,处理进程已经使用完,所以不出错;而在单核系统中,同时只有一个进程在运行,如果写入日志文件的操作晚于GUI线程释放内存的操作,则系统会出现问题。 找到了问题的根源所在,修改就很简单了,方案有两种: 教训: March 22 并行与分布式计算中的一些概念最近在看一些并行与分布式计算的一些书籍和资料,发现不同的文献对一些概念的描述并不是一致的。我就自己的理解汇总和整理了一 些想关概念。 串行(Sequential)计算: 一个处理器依次执行指令,单就一个线程而言,本质上是串行计算的。 Flynn分类法 并行计算机系统绝大部分为MIMD系统,如: 并行程序进程间通信的方式可分为:共享存储器方式、消息传递方式。 我认为最好用一种库来支持并发性,并且该库不需要主语方扩展就能够实现。 C++并行与分布式编程标准: 集中式处理系统: 某种处理任务被集中到一个处理单元上,系统为星型结构,一般只有一个核心处理单元;即使核心处理单元有双机备份, 也属于集中式处理系统。 分布式处理系统: 某种处理任务被分解到多个处理器上(通常是较粗粒度的并行),系统为扁平结构,一般上层有一个控制中心,下层有多个 处理单元,通过下层多个处理单元的数量/功能扩展,来提高整个系统的处理性能。处理任务有两种分解方法:一种是同类处理任务的分解, 属于数量扩展;另一种是按功能不同进行分解,属于功能扩展;两种分解方法一般都混合使用。 我个人认为分布式计算与并行计算的本质是一样的,或者说分布式计算是一种特殊的并行计算。从任务划分和消息的传递上,分布式计算都要比并行计算粒度要粗。有人说分布式计算是进程级别上的协作,而并行计算是线程级别上的协作,也有一定道理。 参考: March 21 计算机体系结构中所指的并行性计算机体系结构中所指的并行性(Parallelism),是指计算机系统具有可以同时进行运算或操作的特性,包括同时性与并发性两种含义。 February 26 OpenMp基本原理最近在研究共享存储模型下的并行程序设计,找了一些书籍和相关资料来看,重点看了OpenMp官方标准2.5版。 OpenMP是共享存储模型下并行程序设计这一领域最为流行的一个标准,它是一个跨平台、跨编译器、高可移植性的方案,而且现在已被大多数主流厂商所支持并实现。 OpenMp规范包括三个方面:编译器制导语句(Compiler Directives)、运行库(Runtime Library Routions)、环境变量(Environment)。OpenMP依赖用户指定编译器和运行时系统的操作以实现程序的并行运行。OpenMP兼容的实现不要求对依赖性、冲突、死锁、竞争和程序不确定性导致的问题进行检测。用户必须自己保证应用程序的正确性。 OpenMP API采用分支-合并(fork-join)模型来实现并行执行。OpenMP程序执行时的初始线程是串行执行的。当一个线程遇到一个并行结构(parallel construct)时,这个线程将创建一个包含自身在内的线程组(team),并且自己变成这个线程组的主线程(master thread)。这个新的线程组中的所有线程执行这个并行结构中的代码。在这个并行结构的最后隐含有一个屏障(barrier)。只有主线程才能执行并行结构以后的代码。一个程序中可以指定任意数目的并行结构,并且允许嵌套。 OpenMP提供一个松一致性(relaxed-consistency),共享内存(shared-memory)的模型。所有的OpenMP线程可以检索或存储主存中的变量。另外,每个线程允许有自己对主存的临时视图(temporary view)。临时视图并不是OpenMP内存模型所必须的,但这个概念可以表示多种实际中可能介入在线程与主存之间的结构,例如寄存器、缓存或者其它的局部存储器等。临时视图允许线程缓存变量而不必每次都访问主存。 parallel制导语句可以决定相关并行结构中变量的可访问性,变量可以是共享的(shared)和私有的(private)。并行结构中访问的共享变量和并行结构外的原始的共享变量是同一个版本。而对于私有变量,每个参予该并行结构的线程(除了该线程组的主线程)都将在主存中复制一个该变量的副本。对于私有变量的访问,都是对当前线程中该变量的私有版本进行访问。 内存模型之所以具有松一致性是因为于每个线程的临时视图并不总是与主存一致。如果多个线程在没有同步机制的情况下修改和检索同一个变量,则产生的结果是未知的。OpenMP的刷新操作(flush opteration)强制临时视图与主存保持一制性。 |
|
|