当前位置: 首页 > news >正文

并发数据结构-1.4 池

原文链接译文链接,译者:huavben,校对:周可人

实现高效并发栈和队列的大部分挑战来自于一个被插入的元素可以被删除这一需求。并发池是一种支持插入和删除操作的数据结构,它允许删除操作移除任何一个已经被插入的,并且没有在随后被删除的元素。这样的弱需求提供了提高并发性能的机会。

一个高效的并发池可以使用任意静态一致的计数器来构建。在这样的并发池中,元素被置于数组当中,fetch-and-inc操作决定插入操作在哪个位置存储元素,同样的,fetch-and-inc操作决定删除操作在哪个位置获得元素。每一个数组元素都包含了一个表示满/空的比特位或者等效的机制,来表明在相应的位置,将要删除的元素已经存在。在这种策略下,使用combining tree,combining funnel,counting network,diffracting tree中的任何一个技术都可以并行化共享技术器,解决这一主要的瓶颈来创建出一个高吞吐量的共享并发池。此外,一个类似栈的池可以使用一个允许增加和减少操作的计数器来实现,然后利用以上技术中的一种来并行化.

最后,在前文中说讨论的消除技术(elimination technique)可以使用在利用combining tree,combining funnel,counting network,diffracting tree等技术实现的并发池中:假如在树中插入和删除操作相遇,那么删除操作可以获取插入操作插入的值,之后两个操作就不用继续遍历这个结构树。这项技术在高负载下能表现出良好的高性能.

上述的这些实现的缺点是,它们在低复杂的情况下性能糟糕。而且,在做负载分布工作的时候,这些实现并不允许我们如同那些专门为负载分布设计的池一样,得到具体的位置信息。

负载均衡算法涉及到一个任务池集合,每个任务池中有一些工作单元,其中每一个任务池都被本地化到一个处理器上。当线程创建了工作项之后就把它们置于本地化的任务池中,依靠负载均衡算法确保任务池中的工作数量都是均衡的。这样就避免了其他处理器仍然忙碌于自己工作的时候,有些处理器却处于空闲状态。大体上有两种解决这类问题的算法:工作共享(work sharing )和工作窃取(work stealing )。在工作共享方案中,每一个处理器尝试不断地将自身任务池中的工作卸下,放到其他任务池中。在工作窃取模式下,一个线程已经完成了自己的工作后就会去窃取其他任务池中的工作去执行。两种方案通过随机选择任务池来平衡工作或窃取工作。

传统工作窃取技术是Arara等人提出的,它基于一个无锁结构的双向队列。该双向队列只允许一个线程(该任务池的本地线程)在队列的一端进行操作,在另一端只允许弹出操作,并且允许在这一端的并发弹出操作在线程相互干扰的情况下中止。在这样的约束下,双向队列适合于任务窃取,并且这种约束允许一种简单的实现方式,即本地线程用低开销的load and store操作来进行插入和删除,只有当它和其他非本地删除线程竞争队列里的最后一个任务的时候,才会依赖昂贵的CAS操作。

在一些案例中已经清晰表明一次窃取多个任务的效果是令人满意的。一个非阻塞的多任务窃取算法由Hendler与Shavit在PODC(2002)上提出。在一些案例中同样表明通过使用 同类工作项信息来决定窃取那些工作是可取的。另外在SPAA(2000)上,Acar等人提出了一种位置引导(locality-guided)的窃取算法. 

相关文章:

  • [TestLink]搭建指南(ubuntu)
  • iOS版本、iPhone版本、Xcode版本比对
  • 设计模式--享元模式
  • KVO 键值观察者
  • 复制含有随机指针节点的链表
  • Android 文件式数据库Realm
  • mobAndroid免费验证短信
  • 【css3】浏览器内核及其兼容性
  • 一个苹果开发者的苹果表体验报告
  • 责任链模式
  • C 数据结构与算法系列 插入排序
  • spring-001-Ioc 顶层容器
  • Android自动化测试之Monkeyrunner使用方法及实例
  • 【案例】slave_net_timeout 问题一则
  • Node+Express+node-mysql 实战于演习 全套mysql(增删改查)
  • ABAP的include关键字,Java的import, C的include和C4C ABSL 的import比较
  • Laravel Telescope:优雅的应用调试工具
  • RedisSerializer之JdkSerializationRedisSerializer分析
  • Spark RDD学习: aggregate函数
  • vue+element后台管理系统,从后端获取路由表,并正常渲染
  • Zepto.js源码学习之二
  • 订阅Forge Viewer所有的事件
  • 基于Android乐音识别(2)
  • 技术发展面试
  • 容器服务kubernetes弹性伸缩高级用法
  • 数据仓库的几种建模方法
  • 小程序上传图片到七牛云(支持多张上传,预览,删除)
  • 一起参Ember.js讨论、问答社区。
  • 字符串匹配基础上
  • Python 之网络式编程
  • Semaphore
  • Unity3D - 异步加载游戏场景与异步加载游戏资源进度条 ...
  • 第二十章:异步和文件I/O.(二十三)
  • ###51单片机学习(1)-----单片机烧录软件的使用,以及如何建立一个工程项目
  • (02)Cartographer源码无死角解析-(03) 新数据运行与地图保存、加载地图启动仅定位模式
  • (AtCoder Beginner Contest 340) -- F - S = 1 -- 题解
  • (LeetCode C++)盛最多水的容器
  • (ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY)讲解
  • (接口自动化)Python3操作MySQL数据库
  • (未解决)macOS matplotlib 中文是方框
  • (五)关系数据库标准语言SQL
  • (一)u-boot-nand.bin的下载
  • (转)Android学习系列(31)--App自动化之使用Ant编译项目多渠道打包
  • .MyFile@waifu.club.wis.mkp勒索病毒数据怎么处理|数据解密恢复
  • .net 4.0 A potentially dangerous Request.Form value was detected from the client 的解决方案
  • .NET 6 在已知拓扑路径的情况下使用 Dijkstra,A*算法搜索最短路径
  • .NET CLR Hosting 简介
  • .NET Core 成都线下面基会拉开序幕
  • .net 桌面开发 运行一阵子就自动关闭_聊城旋转门家用价格大约是多少,全自动旋转门,期待合作...
  • .Net(C#)自定义WinForm控件之小结篇
  • .netcore 如何获取系统中所有session_如何把百度推广中获取的线索(基木鱼,电话,百度商桥等)同步到企业微信或者企业CRM等企业营销系统中...
  • .net与java建立WebService再互相调用
  • @for /l %i in (1,1,10) do md %i 批处理自动建立目录
  • @RequestParam @RequestBody @PathVariable 等参数绑定注解详解
  • @开发者,一文搞懂什么是 C# 计时器!