如果我有代码import { Injectable } from '@angular/core';
import { Headers, Http, Response } from '@angular/http';
import 'rxjs/Rx';
import { Observable } from 'rxjs/Observable';
@Injectable()
export class ServerService {
constructor(private http: Http) {}
storeServers(servers: any[]) {
const headers = new Headers({'Content-Type': 'application/json'});
// return this.http.post('https://udemy-ng-http.firebaseio.com/data.json',
// servers,
// {headers: headers});
return this.http.put('https://udemy-ng-http.firebaseio.com/data.json',
servers,
{headers: headers});
}
getMegyek() {
return this.http.get('http://localhost/Varosok/Controller/Controller/ControllerCity.php?content=megyek')
.map(
(response: Response) => {
const data = response.json();
/*for (const server of data) {
server.name = 'FETCHED_' + server.name;
}*/
return data;
}
)
.catch(
(error: Response) => {
return Observable.throw('Something went wrong');
}
);
}
getAppName() {
return this.http.get('https://udemy-ng-http.firebaseio.com/appName.json')
.map(
(response: Response) => {
return response.json();
}
);
}
}
,现在我知道执行此操作需要多个CPU级别的操作,但是将a = a + 1
定义为a
怎么使这些多个事务原子化?
是否更改了CPU指令的执行方式。我以为它将以某种方式将指令数减少到1,这样任何上下文切换都不会导致不可靠的结果,但是它是如何做到的呢?
如果编译器总是可以创建这样的代码,为什么不总是这样做呢?
答案 0 :(得分:6)
如果有一个原子指令可以发布(用于已知的可能的原子操作),那么该原子指令将被发布,否则它将具有锁定机制。
有一个函数(C ++ 17)告诉您原子类型是否始终是无锁的:is_always_lock_free
。
请注意,如果此函数返回false
,则至少某些操作不是非锁定的(不一定全部锁定)。这些非无锁操作通常会比原子操作贵(它们本身比传统操作贵)。
并非所有硬件都支持原子操作的所有组合,因此不同的编译器后端将生成不同的解决方案,有时使用单个原子操作,有时使用锁定机制。
因此它不能总是创建这样的1指令代码。
答案 1 :(得分:3)
[B] ut如何将std :: atomic定义为多个 交易是原子的吗?
它不会使“多个交易”成为任意表达式中的原子(例如,在您的a = a + 1
示例中无济于事)。相反,您需要使用像a++
这样的操作,它必须保证是原子的。在这种情况下,其实现方式取决于编译器和硬件,但是最常见的策略是:
lock add
指令。通过检查生成的程序集,您可以检查编译器和硬件组合上的行为。有时这很棘手,因为编译器可能会调用运行时库中实现的函数,在这种情况下,您必须检查该函数的源代码或反汇编代码。这意味着,如果运行时库的实现不同,则同一二进制文件可以在不同的主机上具有不同的原子操作实现!
如果编译器总是可以创建这样的代码,为什么不总是这样做 那?
编译器并不总是生成这些,因为它们在硬件级别上很昂贵。例如,在大多数现代CPUs 1 中,正常(非原子)添加通常需要1个周期或更短的 2 ,而原子添加可能需要15至100个周期。通常,使用CAS或LL-SC的方法速度甚至更慢,并且需要重试循环,从而增大了二进制文件的大小。
1 在某些微控制器类CPU上可能只有几个周期-但是原子操作通常不太重要,因为可能没有多个内核。
2 这取决于您的测量方式-加法通常需要一个周期完成 complete (等待时间),但是您通常可以在同一时间执行多个独立的加法周期。例如,现代的Intel CPU可以在一个周期内执行四个。