我有两个线程共享一个 uint64_t 变量。第一个线程只是从变量中读取,而另一个线程只是写入。如果我不使用互斥/自旋锁/原子操作等同步它们,是否有可能从写入的写入线程读取另一个值?读取由写入线程写入的旧值并不重要。
例如,写入线程将变量增加到 0 到 100 之间,读取线程打印该值。那么,是否有可能在屏幕上看到不同于 [0-100] 范围的值。目前我没有看到任何不同的值,但我不确定它会导致竞争条件。
提前致谢。
我们一直使用两台相同的 Skylake 服务器,具有完全相同的软件、Centos 7 操作系统和 BIOS 设置。除了延迟性能之外,一切都一样。我们的软件使用的是AVX512。
在测试中,我注意到 AVX512 每次都会降低其中一个系统的性能(增加延迟)。存在显着的性能差异。我检查了一切,一切都一样。
我应该怎么做才能解决这个问题?哪个工具可以提供帮助?
提前致谢..
sudo lshw -class cpu
*-cpu:0
description: CPU
product: Intel(R) Xeon(R) Gold 6154 CPU @ 3.00GHz
vendor: Intel Corp.
vendor_id: GenuineIntel
physical id: 400
bus info: cpu@0
version: Intel(R) Xeon(R) Gold 6154 CPU @ 3.00GHz
slot: CPU1
size: 3GHz
capacity: 4GHz
width: 64 bits
clock: 1010MHz
capabilities: lm fpu fpu_exception wp vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts …Run Code Online (Sandbox Code Playgroud) 我有一个问题需要了解是否有更好的解决方案。我编写了以下代码,将一些变量从编写器线程传递到读取器线程。这些线程固定到共享相同 L2 缓存的不同 CPU(禁用超线程)。
writer_thread.h
struct a_few_vars {
uint32_t x1;
uint32_t x2;
uint64_t x3;
uint64_t x4;
} __attribute__((aligned(64)));
volatile uint32_t head;
struct a_few_vars xxx[UINT16_MAX] __attribute__((aligned(64)));
Run Code Online (Sandbox Code Playgroud)
reader_thread.h
uint32_t tail;
struct a_few_vars *p_xxx;
Run Code Online (Sandbox Code Playgroud)
写入线程增加头变量,读取线程检查头变量和尾变量是否相等。如果它们不相等,则按如下方式读取新数据
while (true) {
if (tail != head) {
.. process xxx[head] ..
.. update tail ..
}
}
Run Code Online (Sandbox Code Playgroud)
性能是迄今为止最重要的问题。我使用的是 Intel Xeon 处理器,读取器线程每次都会从内存中获取 head 值和 xxx[head] 数据。我使用对齐数组来实现无锁
就我而言,是否有任何方法可以尽快将变量刷新到读取器CPU缓存中。我可以从写入器 CPU 触发读取器 CPU 的预取吗?如果存在的话,我可以使用 __asm__ 来使用特殊的英特尔指令。总之,在固定到不同 CPU 的线程之间传递结构中的变量的最快方法是什么?
提前致谢