我理解通过依赖缓存一致性协议(MESI/MESIF)xsub(),可以在不使用LOCK前缀的操作上保证原子性.
1)缓存一致性协议如何做到这一点?
它让我想知道缓存一致性协议是否可以强制执行原子性,为什么我们需要特殊的原子类型/指令等?
2)如果MOSI跨多核系统实现原子指令那么目的是LOCK什么?遗产?
3)如果MOSI实现原子指令并且MOSI用于所有指令 - 那么为什么原子指令成本太高?当然,性能应该与普通指令相同.
一方面,维基百科写了乱序执行的步骤:
- 取指令。
- 指令分派到指令队列(也称为指令缓冲区或保留站)。
- 指令在队列中等待,直到其输入操作数可用。然后允许该指令在较早、较旧的指令之前离开队列。
- 指令被发布到适当的功能单元并由该单元执行。
- 结果在排队。
- 只有在所有较旧的指令将其结果写回寄存器文件后,才会将该结果写回寄存器文件。这称为毕业或退休阶段。
类似的信息可以在《计算机组织与设计》一书中找到:
为了让程序表现得像在一个简单的有序流水线上运行,指令获取和解码单元需要按顺序发出指令,这允许跟踪依赖关系,并且提交单元需要将结果写入寄存器和程序获取顺序中的内存。这种保守的模式被称为有序提交……今天,所有动态调度的管道都使用有序提交。
因此,据我所知,即使指令以乱序方式执行,其执行结果也会保存在重新排序缓冲区中,然后以确定性顺序提交到内存/寄存器。
另一方面,有一个众所周知的事实,即现代 CPU 可以为性能加速目的重新排序内存操作(例如,可以重新排序两个相邻的独立加载指令)。维基百科在这里写到。
您能否解释一下这种差异?
cpu cpu-architecture dynamic-execution instructions pipelining
最近我偶然发现了http://dask.pydata.org/en/latest/ 因为我有一些只能在单核上运行的 Pandas 代码,我想知道如何利用我的其他 CPU 核。dask 可以很好地使用所有(本地)CPU 内核吗?如果是,它与熊猫的兼容性如何?
我可以对 Pandas 使用多个 CPU 吗?到目前为止,我阅读了有关发布 GIL 的信息,但这一切似乎都相当复杂。
在不同的机器上获得不同的结果,并且想知道这是否是预期的行为或某些CPU实施'>>>操作时可能出现的错误?
Linux qemux86-64 4.18.41-yocto-standard #1 SMP PREEMPT Tue Oct 8 20:33:31 UTC 2019 x86_64 GNU/Linux
root@qemux86-64:~# node --v8-options|head -n 1
SSE3=1 SSSE3=1 SSE4_1=0 SAHF=1 AVX=0 FMA3=0 BMI1=0 BMI2=0 LZCNT=0 POPCNT=0 ATOM=0
root@qemux86-64:~# node -v
v8.12.0
root@qemux86-64:~# node -e 'console.log(undefined >>> 0)'
4294967295
Run Code Online (Sandbox Code Playgroud)
(未定义>>> 0)在我测试的其他计算机上的值为0。但是,然后启用 CPU功能: AVX FMA3 BMI1 BMI2 LZCNT POPCNT
我的 Tensorflow 模型大量使用数据预处理,这些数据预处理应在 CPU 上完成,以使 GPU 开放用于训练。
top - 09:57:54 up 16:23, 1 user, load average: 3,67, 1,57, 0,67
Tasks: 400 total, 1 running, 399 sleeping, 0 stopped, 0 zombie
%Cpu(s): 19,1 us, 2,8 sy, 0,0 ni, 78,1 id, 0,0 wa, 0,0 hi, 0,0 si, 0,0 st
MiB Mem : 32049,7 total, 314,6 free, 5162,9 used, 26572,2 buff/cache
MiB Swap: 6779,0 total, 6556,0 free, 223,0 used. 25716,1 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ …Run Code Online (Sandbox Code Playgroud) 当我谷歌搜索时,有一些答案说在kubernetes中,100ms cpu意味着你将使用一个cpu核心的1/10时间,而2300ms cpu意味着你将充分使用2个核心和3/10时间另一个CPU核心。这是对的吗?
我只是想知道在 kubernetes 中使用低于 1000ms 的 cpu 请求时,多个线程是否可以同时在多个核心上并行运行。
根据ARM 文档,线程 ID 寄存器类似于TPIDR_EL0或TPIDR_EL1,
提供存储软件线程和进程 ID 的位置,以用于操作系统管理目的。这些寄存器对处理器行为没有影响。
为什么有人想要将线程 ID 存储在特殊寄存器中?ARM 处理器是否要求线程在内存中拥有特殊的结构,就像 MMU 一样?线程对于 ARM 来说是特殊的东西吗?ARM 期望在某个地方找到它吗?或者我可以在不使用这个寄存器的情况下(有效地)实现线程吗?
我这么问是因为我在 Fuchsia OS 的 Zircon 内核上找到了这段代码:
static inline void arch_set_current_thread(Thread* t) {
__arm_wsr64("tpidr_el1", (uint64_t)&t->arch_.thread_pointer_location);
__isb(ARM_MB_SY);
}
Run Code Online (Sandbox Code Playgroud)
在启动时,它创建一个线程并将其指针存储在tpidr_el1
在 C 等语言中,不同线程对同一内存位置的不同步读取和写入是未定义的行为。但在 CPU 中,缓存一致性表示,如果一个核心写入某个内存位置,然后另一个核心读取它,则另一个核心必须读取写入的值。
如果上一层将丢弃内存层次结构的连贯抽象,为什么处理器需要费心暴露它呢?为什么不让缓存变得不连贯,并要求软件在想要共享某些内容时发出特殊指令呢?
有时你需要知道你的程序在高峰期间需要多少内存,但可能不太关心这个高峰何时发生以及持续多长时间等。Pytorch 有一个很好的工具,可以报告在 GPU 上运行时的内存使用情况,您只需在程序结束时调用一次:
memory_usage = torch.cuda.memory_stats()["allocated_bytes.all.peak"]
torch.cuda.reset_peak_memory_stats()
Run Code Online (Sandbox Code Playgroud)
这段代码非常简单,因为它使您无需运行一个单独的线程每毫秒监视您的内存并找到峰值。
现在我的问题是:为什么这只适用于 GPU?我找不到像 torch.cpu.memory_stats() 这样的东西。在CPU上运行时,这个挂件是什么?
cpu ×10
multicore ×2
arm ×1
armv8 ×1
assembly ×1
atomic ×1
c ×1
cgroups ×1
cpu-cache ×1
dask ×1
fuchsia ×1
gpu ×1
instructions ×1
intel ×1
javascript ×1
kernel ×1
kubernetes ×1
memory ×1
node.js ×1
pandas ×1
performance ×1
pipelining ×1
preprocessor ×1
python ×1
pytorch ×1
tensorflow ×1
v8 ×1
x86 ×1