atomic

什么时候使用volatile关键字?

自作多情 提交于 2020-07-28 08:58:59
想必大家平时都见过volatile关键字,可是你知道什么时候需要使用volatile关键字吗? 直接看下面代码: int a = 100; while (a == 100) { // code } 这段程序编译时,如果编译器发现程序始终没有企图改变a的值,那它可能就会优化这段代码,变成while(true)的死循环使得程序执行的更快,然而编译器有时候也会做过度优化,它有时候可能没有意识到程序会改变a的值,却做了这种优化导致程序没有产生预期的行为。 这里为了产生预期的行为,需要阻止编译器做这种优化,可以使用volatile关键字修饰。 volatile int a = 100; volatile关键字和const关键字相对应,const关键字告诉编译器其修饰的变量是只读的,编译器根据只读属性做一些操作,而volatile关键字告诉编译器其修饰的变量是 易变的 ,同理编译器根据易变属性也会做一些操作。它会确保修饰的变量每次都读操作都从内存里读取,每次写操作都将值写到内存里。volatile关键字就是给编译器做个提示,告诉编译器不要对修饰的变量做过度的优化,提示编译器该变量的值可能会以其它形式被改变。 volatile修饰结构体时,结构体的成员也是volatile的吗 struct A { int data; }; volatile A a; const A b;

芯片Timing sign-off Corner理解

半世苍凉 提交于 2020-07-27 18:28:27
参考博文:http://blog.sina.com.cn/s/blog_5ced60e80102y7pd.html 一颗健壮的IC芯片应该具有能屈能伸的品质,他需要适应于他所在应用范围内变化的温度、电压,他需要承受制造工艺的偏差,这就需要在设计实现过程中考虑这些变化的温度、电压和工艺偏差。 在STA星球,用 library PVT、RC corner跟OCV 来模拟这些不可控的随机因素。在每个工艺结点,通过大量的建模跟实测,针对每个具体的工艺,foundary厂都会提供一张推荐的timingsignoff表格, 建议需要signoff的corner及各个corner需要设置的ocv跟margin。这些corner能保证大部分芯片可以承受温度、电压跟工艺偏差,一个corner=libraryPVT+ RC corner + OCV,本文将关注于library PVT。 ------OCV(on-chip-variation)也是用来模拟cell的PVT及线的RC变化,与前面两个不同的是,前两者是芯片全局的PVT/RC Corner,OCV是芯片上内的局部偏差(包括process 、 voltage、temperature、network RC)。比如在STA分析setup时,并不是用最慢的library PVT来signoff就是最差情况,对于capture

java多线程面试题整理及答案(2019年)

自闭症网瘾萝莉.ら 提交于 2020-07-27 10:46:30
1) 什么是线程? 线程是操作系统能够进行运算调度的最小单位,它被包含在进程之中,是进程中的实际运作单位。程序员可以通过它进行多处理器编程,你可以使用多线程对 运算密集型任务提速。比如,如果一个线程完成一个任务要100毫秒,那么用十个线程完成改任务只需10毫秒。Java在语言层面对多线程提供了卓越的支 持,它也是一个很好的卖点。 2) 线程和进程有什么区别? 线程是进程的子集,一个进程可以有很多线程,每条线程并行执行不同的任务。不同的进程使用不同的内存空间,而所有的线程共享一片相同的内存空间。别把它和栈内存搞混,每个线程都拥有单独的栈内存用来存储本地数据。 3) 如何在Java中实现线程? 在语言层面有三种方式。java.lang.Thread 类的实例就是一个线程但是它需要调用java.lang.Runnable接口来执行,由于线程类本身就是调用的Runnable接口所以你可以继承 java.lang.Thread 类或者直接调用Runnable接口来重写run()方法实现线程。第三种 实现Callable<>接口并重写call方法。 4) 用Runnable还是Thread? 这个问题是上题的后续,大家都知道我们可以通过继承Thread类或者调用Runnable接口来实现线程,问题是,那个方法更好呢?什么情况下使 用它?这个问题很容易回答,如果你知道Java不支持类的多重继承

Linux 操作系统原理 — 日志结构的文件系统与日志文件系统

≡放荡痞女 提交于 2020-07-27 09:57:18
目录 文章目录 目录 日志结构的文件系统 日志文件系统 日志结构的文件系统 技术的改变会给当前的文件系统带来压力。这种情况下,CPU 会变得越来越快,磁盘会变得越来越大并且越来越便宜(但不会越来越快)。内存容量也是以指数级增长。但是磁盘的寻道时间(除了固态盘,因为固态盘没有寻道时间)并没有获得提高。 这些因素结合起来意味着许多系统文件中出现性能瓶颈。为此,Berkeley 设计了一种全新的文件系统,试图缓解这个问题,这个文件系统就是日志结构文件系统(Log-structured File System,LFS)。 日志结构文件系统由 Rosenblum和 Ousterhout于 90 年代初引入,旨在解决以下问题: 不断增长的系统内存 顺序 I/O 性能胜过随机 I/O 性能 现有低效率的文件系统 文件系统不支持 RAID(虚拟化) 另一方面,当时的文件系统不论是 UNIX 还是 FFS,都有大量的随机读写(在 FFS 中创建一个新文件至少需要 5 次随机写),因此成为整个系统的性能瓶颈。同时因为 Page cache 的存在,随机读不是主要问题,随着越来越大的内存,大部分的读操作都能被 cache,因此 LFS 主要要解决的是减少对硬盘的随机写操作。 在这种设计中,inode 甚至具有与 UNIX 中相同的结构,但是现在它们分散在整个日志中,而不是位于磁盘上的固定位置。所以

99 道 Java 多线程面试题,看完我跪了!

醉酒当歌 提交于 2020-07-27 01:24:00
今天给大家更新的是一篇关于多线程面试的文章,是根据时下热门的面试内容给大家进行总结的,如有雷同,请多见谅。 本篇文章属于干货内容!请各位读者朋友一定要坚持读到最后,完整阅读本文后相信你对多线程会有不一样感悟,下次面试和面试官也能杠一杠相关内容了。 1.什么是进程? 进程是系统中正在运行的一个程序,程序一旦运行就是进程。 进程可以看成程序执行的一个实例。进程是系统资源分配的独立实体,每个进程都拥有独立的地址空间。一个进程无法访问另一个进程的变量和数据结构,如果想让一个进程访问另一个进程的资源,需要使用进程间通信,比如管道,文件,套接字等。 2.什么是线程? 是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。 3.线程的实现方式? 1.继承Thread类 2.实现Runnable接口 3.使用Callable和Future 4.Thread 类中的start() 和 run() 方法有什么区别? 1.start()方法来启动线程,真正实现了多线程运行。这时无需等待run方法体代码执行完毕,可以直接继续执行下面的代码;通过调用Thread类的start()方法来启动一个线程, 这时此线程是处于就绪状态, 并没有运行。然后通过此Thread类调用方法run(

老白学编程-GCC的原子操作

二次信任 提交于 2020-07-26 19:08:07
记录数值原子操作 背景 c/c++ 中, ++或-- 又或是赋值, 都不是原子操作,多线程时,使用锁和互斥量又太重,对性能造成一定损失。 原子操作API 为了提高赋值操作的效率,gcc提供了一组api,通过汇编级别的代码来保证赋值类操作的原子性,相对于涉及到操作系统系统调用和应用层同步的锁和互斥量,这组api的效率要高很多。 n++类 type __sync_fetch_and_add(type *ptr, type value, ...); // m+n type __sync_fetch_and_sub(type *ptr, type value, ...); // m-n type __sync_fetch_and_or(type *ptr, type value, ...); // m|n type __sync_fetch_and_and(type *ptr, type value, ...); // m&n type __sync_fetch_and_xor(type *ptr, type value, ...); // m^n type __sync_fetch_and_nand(type *ptr, type value, ...); // (~m)&n /* 对应的伪代码 */ { tmp = *ptr; *ptr op= value; return tmp; }

Are X86 atomic RMW instructions wait free

社会主义新天地 提交于 2020-07-21 03:42:32
问题 On x86, atomic RMW instructions like lock add dword [rdi], 1 are implemented using cache locking on modern CPUs. So a cache line is locked for duration of the instruction. This is done by getting the line EXCLUSIVE/MODIFIED state when value is read and the CPU will not respond to MESI requests from other CPU's until the instruction is finished. There are 2 flavors of concurrent progress conditions, blocking and non-blocking. Atomic RMW instructions are non-blocking. CPU hardware will never

Are X86 atomic RMW instructions wait free

隐身守侯 提交于 2020-07-21 03:40:46
问题 On x86, atomic RMW instructions like lock add dword [rdi], 1 are implemented using cache locking on modern CPUs. So a cache line is locked for duration of the instruction. This is done by getting the line EXCLUSIVE/MODIFIED state when value is read and the CPU will not respond to MESI requests from other CPU's until the instruction is finished. There are 2 flavors of concurrent progress conditions, blocking and non-blocking. Atomic RMW instructions are non-blocking. CPU hardware will never

Are writes on the PCIe bus atomic?

99封情书 提交于 2020-07-09 07:36:11
问题 I am a newbie to PCIe, so this might be a dumb question. This seems like fairly basic information to ask about PCIe interfaces, but I am having trouble finding the answer so I am guessing that I am missing some information which makes the answer obvious. I have a system in which I have an ARM processor (host) communicating to a Xilinx SoC via PCIe (device). The endpoint within the SoC is an ARM processor as well. The external ARM processor (host) is going to be writing to the register space

How to mix atomic and non-atomic operations in C++?

故事扮演 提交于 2020-07-08 05:25:09
问题 The std::atomic types allow atomic access to variables, but I would sometimes like non-atomic access, for example when the access is protected by a mutex. Consider a bitfield class that allows both multi-threaded access (via insert) and single-threaded vectorized access (via operator|=): class Bitfield { const size_t size_, word_count_; std::atomic<size_t> * words_; std::mutex mutex_; public: Bitfield (size_t size) : size_(size), word_count_((size + 8 * sizeof(size_t) - 1) / (8 * sizeof(size