C/C++ 中的两条指令中是否写入或加载了一个 128 位 int?

Is a 128 bit int written or loaded in two instructions in C/C++?

我知道在 C 和 C++ 中存在 int128_t 类型。

如果我有两个线程,一个正在从包含这个 128 位整数的内存位置读取,另一个正在写入它。

这个值是否有可能被写为两次 64 位整数写入还是一次 128 位整数写入?

C 和 C++ 都不需要具有 int128_t 类型,尽管如果编译器确实支持该类型,那么它 必须 signed 2补 128 位整数类型。但是原子性不是必需的。

同时读取和写入非原子的 any 类型的行为是 undefined

在 C++ 中,如果您可以使用 std::atomic<int128_t>,并且如果您的平台 确实 具有原子 int128_t,那么这将比 typedef.

否则,在 C 语言中,您的编译器可能具有原子 128 位整数类型。如果没有,那么您可以使用内联汇编推出您自己的版本。

首先,C++中没有没有 int128_t类型。最大的标准类型是int64_t.

其次,某些平台提供 128 位整数类型作为扩展。例如gcc/clang/icc支持__int128类型。

要在多线程场景中正确使用此类型,(与任何其他类型一样!)要么使用适当的同步结构保护访问,要么使用 std::atomic<__int128>。支持__int128的平台通常也支持它的原子版本。

为了满足您的好奇心,我不知道目前使用的任何常见硬件是否可以原生支持 128 位整数。

其他答案中讨论了支持。我将讨论实施问题。

通常在从内存中读取时,编译器会发出处理器指令以将数据从内存中提取到寄存器中。这可能是原子的,具体取决于数据总线在处理器和内存之间的设置方式。

如果您的处理器支持 128 位传输并且内存支持 128 位数据总线,这可能是单次获取(或写入)。

如果您的处理器支持 128 位 {register} 传输,但数据总线较小,则处理器将执行足够的提取以从内存传输数据。这可能是也可能不是原子的,具体取决于您对原子的定义(这是一个处理器指令,但可能需要多次提取)。

对于不支持 128 位寄存器传输的处理器,编译器将发出足够的指令将内存读入寄存器。这是用于寄存器到内存或内存到寄存器的传输。

对于内存到内存的传输(例如变量赋值),编译器可能会选择使用块读写(如果您的处理器支持块读写)。一些处理器支持 SIMD,其他处理器可能有块传输指令。例如,ARM 有 LDM(load multiple)和 STM(store multiple)指令,用于从内存中加载多个寄存器并将多个寄存器存储到内存中。块读写的另一种方法是使用 DMA 设备(如果存在)。 DMA 可以在处理器执行其他指令的同时传输数据。但是,使用 DMA 的开销可能需要比使用 16 个 8 字节(字节)传输更多的指令。

综上所述,编译器不需要支持int128_t。如果它们确实支持,则有多种方法可以传输数据,具体取决于处理器和平台硬件支持。查看汇编语言以查看编译器为支持 int128_t 发出的指令。