为了保证并行程序执行的正确性和高效性,构建一个共享存储多处理器系统的硬件必须要解决缓存一致性、存储一致性和同步原语的支持等问题。

被广泛使用的同步原语包括锁lock、栅栏barrier和点对点同步(signal和wait信号量)。举例来说,锁和栅栏被大量使用在DOALL并行性和具有链式数据结构的应用程序中,而signal/wait同步对流水线DOCROSS并行性来说至关重要。

如今一种很使用的方式是将最低级别的同步原语以原子指令的形式在硬件上实现,然后将其他所有高级别的同步原语在软件中实现。通常在可扩展性(同步延迟和带宽如何随着更大数量的线程而扩展)和无竞争延迟(线程不同时尝试同步所带来的延迟)之间会作出权衡。

对于大型系统来说,在原子指令之上实现的软件栅栏和锁可能不具有足够的可扩展。对于这些系统来说,硬件栅栏的实现很常见。

8.1 锁的实现

8.1.1 对锁实现性能的评估

性能评价标准,考虑锁的实现:

        1)无竞争获取锁延迟:当线程间没有竞争时,获取一个锁所花费的时间。
        2)通信量:总的通信量,是参与竞争锁的线程或者处理器数的函数。通信量可以分为三个子部分,即当一个锁空间时获取产生的通信量、当一个锁不空闲 时锁 获取产生的通信量:锁释放时产生的通信量。
        3)公平性:线程同其他线程相比被允许持有锁的程度。公平性的标准是在一个锁实现中,线程饥饿的情况是否存在,即一个线程不能长时间地持有锁,即使这个锁在这段时间内是空闲的。
         4)存储:需要的存储空间时线程数的函数。一些锁的实现要去一个恒定的存储空间,这个存储空间与共享锁的线程数无关;而另一些锁的实现要求的存储空间是随着共享锁的线程数而线性增长的。

8.1.2 对原子指令的要求

        软件机制并不能扩展,因为执行的静态指令的数量,已经为了查看线程是否能够获得锁而需要检查的变量的数量,都会随着线程数的增加而增加。相反,如果一个原子指令能够执行一系列加载、比较其他指令和存储指令,那么可以实现一个简单的锁

int is_turn;
int is_ready[n] = {0};    // n是处理器数目void Lock(int porcess)
{int other = 1- process;is_ready[process] = TRUE;is_turn = process;while (is_turn == process && is_ready[other] == TRUE)
}void Unlock(int process)
{is_ready[process] = FALSE;
}

   在当今的系统中,大部分的处理器支持将一个原子指令作为最低级的原语,同时基于它还可以构建其他同步原语。一个原子指令以一种不可分割的方式执行一系列的读、修改和写操作,这些操作在执行时不可能分割。

lock: ld    R1, &lockvarbnz   R1, lockst    &lockvar, #1retunlock: st    &lockvar, #0ret 

以上指令必须原子性地执行,“原子”这个词表达了两件事。首先,它意味着要么整个序列都被完整执行,要么其中任何一条指令都不执行。其次,它表达了在任何给定的时间内,只有一条原子指令(无论来自那个处理器)能够被执行。下面列出一些经常使用:

        test-and-set Rx,M: 读取存储在存储单元M的值,将这个值与一个常数进行比较,如果他们想匹配,那么将寄存器Rx中的到存储单元M中。

        fetch-and-op M: 读取存储在在存储单元M的值,对这个值执行操作(如自增、减值、加法、减法),然后将得到的新值存储到存储单元M中。在有些情况下,会指定额外的操作数。

        exchange Rx, M:自动交换在存储单元M中的值和寄存器Rx的值。

        compare-and-swap Rx, Ry, M:比较存储单元M中的值和寄存器Rx中的值,如果它们匹配,将寄存器Ry中的值写到存储单元M中,然后拷贝寄存器Rx中的值到寄存器Ry中。

除了以上指令之外,最通用的一个指令是比较并交换CAS:与test-adn-set指令相比较,它能执行一个比较,但是与之相比较的是一个寄存器中任意值,而不是一个常数;与一个exchange指令相比,它可以交换寄存器和内存中的值,但是需要附加的条件。

读者可能会提出两个问题:

        1)一个原子指令如何确保原子性?
        2)一个原子指令如何被用于同步控制结构?

一个原子指令本质上为程序提供了一个保障:指令所代表的一系列操作将会被完整地执行。

缓存一致性协议提供了原子性被保障的基础。当遇到一个原子指令时,这个缓存一致性协议知道需要保证其原子性。他首先会获得存储单元M的“独家所有权”(通过将其他包含M的缓存块中的拷贝都置为无效)。当获得独家所有权后,这个协议会确保只有只有一个处理器能够访问这个块,而如果其他处理器在此时想要访问的话就会经历缓存缺失,接下来原子指令就可以执行了。而如果其他处理器在此时想要访问的话就会经历缓存缺失,接下来原子指令就可以执行了。在原子指令持续期间,其他处理器不允许“偷走”这个块。

在一个基于总线的多处理器中,一个阻止块(在基于总线的多处理器上)被“偷走”的方法是锁上或者预约总线直到指令完成。

一个更加常用的解决办法(亦可用在非基于总线的多处理器系统中)不是阻止其他对总线的请求,而是使用执行原子指令的处理器的一致性控制器,来对块的其他所有请求延迟响应直到原子指令完成,或者否定确认请求,这样请求者会在未来重复请求。

8.1.3 TS锁

在获取锁的尝试中的第一条指令时test-and-set指令,它原子地执行下面几个步骤:首先从lockvar所在的存储单元中读取值到寄存器R1中(使用一个独占的读指令,如BusRfx或者BusUpgr),将寄存器R1中的值与0相比较。第二条指令时分支指令,当R1中的值非0的时候分支指令回到标签lock,这样锁的获取可以被重新尝试。如果R1中的值是0,就意味着当到达分支指令时,因为原子性,test-and-set指令已经成功了。锁的释放只需要将0赋给lockvar即可,而不需要原子指令,因为此时只有一个线程在临界区,所有只有一个线程能够对锁进行释放,在锁释放的时候不会产生冲突。

lock: t&s    R1, &lockvarbnz    R1, lockretunlock:    st, &lockvar,    #0ret

  评价一下test-and-set锁实现。因为在成功获得一个锁的时候只需要一条原子指令和一条分支指令,所以无竞争获取锁的延迟很低,但是通信量需求非常高。每个锁获取都试图使其他拷贝失效,而不管这个获取成功与否。比如

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/42836.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/42836.shtml
英文地址,请注明出处:http://en.pswp.cn/news/42836.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ARM 作业1

一、思维导图 二、 1. 2. .text 文本段 .globl _start 声明_start:mov r0,#0mov r1,#0fun:cmp r1,#100bhi stopadd r0,r0,r1add r1,r1,#1b fun stop:b stop .end

C++函数模板和类模板

C另一种编程思想称为泛型编程,主要利用的技术是模板 C提供两种模板机制:函数模板和类模板 C提供了模板(template)编程的概念。所谓模板,实际上是建立一个通用函数或类, 其类内部的类型和函数的形参类型不具体指定, 用…

Axios使用CancelToken取消重复请求

处理重复请求:没有响应完成的请求,再去请求一个相同的请求,会把之前的请求取消掉 新增一个cancelRequest.js文件 import axios from "axios" const cancelTokens {}export const addPending (config) > {const requestKey …

如何区分闰年与平年

首先要明白 地球绕太阳运行周期为365天5小时48分46秒(合365.24219天),即一回归年(tropical year)。公历的平年只有365日,比回归年短约0.2422 日,每四年累积约一天,把这一天加于2月末…

Docker安装基础使用练习

目录 1、安装Docker-CE 1)简单使用yum方式安装 ! 2)配置镜像加速: 2、下载系统镜像(Ubuntu、 centos) 1)先查看我们所需的镜像有哪些版本。使用search命令! 2)下载镜像使用的是pul…

【爬虫】P1 对目标网站的背景调研(robot.txt,advanced_search,builtwith,whois)

对目标网站的背景调研 检查 robot.txt估算网站大小识别网站所用技术寻找网站的所有者 检查 robot.txt 目的: 大多数的网站都会包含 robot.txt 文件。该文件用于指出使用爬虫爬取网站时有哪些限制。而我们通过读 robot.txt 文件,亦可以最小化爬虫被封禁的…

vue中实现文字检索时候将搜索内容标红

实现结果 html&#xff1a; <div class"searchBox"><span class"bt">标&#8195&#8195题</span><div class"search"><div class"shuru"><!-- <span class"title">生产经营<…

[leetcode] 707 设计链表

707. 设L计链表 中等 902 相关企业 你可以选择使用单链表或者双链表&#xff0c;设计并实现自己的链表。 单链表中的节点应该具备两个属性&#xff1a;val 和 next 。val 是当前节点的值&#xff0c;next 是指向下一个节点的指针/引用。 如果是双向链表&#xff0c;则还需…

如何批量修改图片名为不同名称

如何批量修改图片名为不同名称&#xff1f;当今社会&#xff0c;因为人们都养成了随手拍照的习惯&#xff0c;所以拥有上千上万张照片的相册已经司空见惯不足为奇。然而&#xff0c;我们在保存这些照片时往往都会碰到一个大难题——电脑中的图片名称千奇百怪&#xff0c;让整个…

C++并发多线程--std::async、std::packaged_task和std::promise的使用

目录 1--std::async的使用 2--std::packaged_task的使用 3--std::promise的使用 1--std::async的使用 std::async用于启动一个异步任务&#xff0c;并返回一个std::future对象&#xff1b;std::future对象里含有异步任务线程入口函数的结果&#xff1b; std::launch::deferr…

完美解决微信小程序使用复选框van-checkbox无法选中

由于小程序使用了vant-ui框架&#xff0c;导致checkbox点击无法选中问题 <van-checkbox value"{{ checked }}" shape"square"><view class"check-content"><view class"checktext">我已阅读并同意>《用户协议》…

opencv-目标追踪

import argparse import time import cv2 import numpy as np# 配置参数 ap argparse.ArgumentParser() ap.add_argument("-v", "--video", typestr,help"path to input video file") ap.add_argument("-t", "--tracker", …

第1天----验证一个字符串是否是另一个字符串的子串

本文我们将学习如何去验证一个字符串是否是另一个字符串的子串。 一、小试牛刀&#xff1a; 题目描述 输入两个字符串&#xff0c;验证其中一个串是否为另一个串的子串。 输入格式 两行&#xff0c;每行一个字符串。 输出格式 若第一个串 s 1 是第二个串 s 2 的子串&#xff0c…

java Spring Boot properties多环境配置拆分文件管理

上文 java Spring Boot yml多环境拆分文件管理优化 我们用yml 做了一个多环境配置文件的拆分管理 我们将 application.yml 改为 application.properties 参考代码如下 spring.profiles.activedev我们知道 yml 是用 : 来区分高低基本 而 properties是直接通过 . 来表达 其他基本…

使用svd 分解的方法对神经网络模型进行压缩(能不能压缩要看秩的大小)

参考和理论 压缩原理代码 import torch import numpy as np torch.manual_seed(0)# ------------------------------------ # n:输入数据维度 # m:输出数据维度 # ------------------------------------ n = 12 m = 10# ------------------------------------ # 随机初始化权…

树形组件浅知

别人写好的轮子&#xff0c;会用即可 首先&#xff0c;需要安装依赖&#xff0c;npm install --save riophae/vue-treeselect 如果使用npm 不行 那么就使用 yarn add --save riophae/vue-treeselect 然后在使用的地方引入即可 // import the componentimport Treeselect from…

微信ipad协议8.0.40 加好友功能

友情链接 geweapi.com 点击即可访问&#xff01; 好友请求验证 小提示&#xff1a; v_3 v_4 可以参考 搜索接口 请求URL&#xff1a; http://域名地址/api/contacts/verifyuser 请求方式&#xff1a; POST 请求头&#xff1a; Content-Type&#xff1a;application/js…

SpringCloud实用篇7——深入elasticsearch

目录 1 数据聚合1.1 聚合的种类1.2 DSL实现聚合1.2.1 Bucket聚合语法1.2.2 聚合结果排序1.2.3 限定聚合范围1.2.4 Metric聚合语法1.2.5.小结 1.3 RestAPI实现聚合1.3.1 API语法1.3.2 业务需求1.3.3 业务实现 2 自动补全2.1 拼音分词器2.2 自定义分词器2.3 自动补全查询2.4 实现…

POJ 1995 Raising Modulo Numbers 快速幂

一、总结 我一开始担心溢出&#xff0c;开了一个无符号的long long&#xff0c;但是直接超时&#xff0c;后来一看它的mod不是很大&#xff0c;于是改成int&#xff0c;直接过了。 二、代码 #include <iostream> using namespace std; int H, Z; int M; int mulMod(in…

P1217 [USACO1.5] 回文质数 Prime Palindromes

P1217 [USACO1.5] 回文质数 Prime Palindromes - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) # [USACO1.5] 回文质数 Prime Palindromes ## 题目描述 因为 $151$ 既是一个质数又是一个回文数&#xff08;从左到右和从右到左是看一样的&#xff09;&#xff0c;所以 $151$ …