代码之家  ›  专栏  ›  技术社区  ›  Marcus Karpoff

是128位int写或加载在两个指令在C/C++?

  •  1
  • Marcus Karpoff  · 技术社区  · 6 年前

    我知道有一个 int128_t 在C和C++中键入。

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

    是否有可能将此值写入两个64位整数写入,还是将其写入一个128位整数写入?

    3 回复  |  直到 6 年前
        1
  •  5
  •   Thomas Matthews    6 年前

    支持在其他答案中讨论。我将讨论实现问题。

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

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

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

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

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

    总之,编译器不需要支持 int128_t . 如果它们确实支持它,那么根据处理器和平台硬件的支持,有各种方法来传输数据。查看汇编语言以查看编译器发出的要支持的指令 国际128 .

        2
  •  5
  •   Bathsheba    6 年前

    C和C++都不需要 int128_t 类型,但如果编译器确实支持该类型,则 必须 是一个 signed 2的补码128位整型。但是原子性不是一项要求。

    阅读和写作的行为 任何 同时键入非原子的是 未定义 .

    在C++中,如果你可以使用 std::atomic<int128_t> 如果你的平台 有原子的 国际128 那就只不过是 typedef

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

        3
  •  3
  •   SergeyA    6 年前

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

    其次,一些平台提供128位整数类型作为扩展。例如,GCC/Clang/ICC支持 __int128 类型。

    为了在多线程场景中正确使用此类型,其中一个场景(与任何其他类型一样!)使用适当的同步构造保护访问,或者使用 std::atomic<__int128> . 支持的平台 _国际128 通常也支持它的原子版本。

    为了满足您的好奇心,我不知道目前使用的任何通用硬件可以支持本机128位整数。