小编Sou*_*a B的帖子

无锁同步总是优于使用锁的同步吗?

在 C++ 中,有一种原子类型std::atomic<T>。该原子类型可能是无锁的,也可能不是,具体取决于类型 T 和当前平台。如果某个类型的无锁实现在类型 T 的平台上可用,那么大多数编译器都会提供无锁atomic<T>。在这种情况下,即使我想要非无锁atomic<T>我也无法拥有它。

C++ 标准决定只保留一个,std::atomic<T>而不是一std::atomic<T>加一std::lock_free<T>(部分针对特定类型实现)。这是否意味着“在任何情况下,当后者可用时,使用非无锁原子类型都会比使用无锁原子类型更好”?(主要是在性能方面而不是易用性方面)。

c++ synchronization lock-free stdatomic

45
推荐指数
4
解决办法
8227
查看次数

stdfloat 中的 floatN_t 是否保证符合 IEEE 标准?

与基本类型 \xe2\x80\x93和\xe2\x80\x93 不同float, C++23 中引入的新类型将始终是 IEEE 标准二进制浮点类型吗?doublelong doublefloatN_t<stdfloat>

\n

固定宽度浮点的 cppreference 页面确实提到了精度和指数位,这与 IEEE 标准相匹配。但该页面并未在任何地方明确提及 IEEE 标准。IEEE 兼容的浮点意味着,它们不仅应该具有相同的精度和指数位,而且该标准还列出了必须以符合标准的方式支持的许多操作。那么这些类型是否严格遵循这一点呢?

\n

c++ floating-point language-lawyer c++23

24
推荐指数
2
解决办法
1094
查看次数

C++ 中原子加载存储的优化

我读过std::memory_orderC++ 并部分理解。但我对此仍然存有一些疑问。

  1. 解释std::memory_order_acquire说,在此加载之前,当前线程中的任何读取或写入都不能重新排序。这是否意味着编译器和 CPU 不允许移动语句下方acquire或上方的任何指令?
auto y = x.load(std::memory_order_acquire);
z = a;  // is it leagal to execute loading of shared `b` above acquire? (I feel no)
b = 2;  // is it leagal to execute storing of shared `a` above acquire? (I feel yes)
Run Code Online (Sandbox Code Playgroud)

我可以推理出为什么在 之前执行加载是非法的acquire。但为什么这对商店来说是非法的呢?

  1. 跳过atomic对象中无用的加载或存储是否违法?因为它们不是volatile,而且据我所知,只有 volatile 有这个要求。
auto y = x.load(std::memory_order_acquire);  // `y` is never used
return;
Run Code Online (Sandbox Code Playgroud)

relaxed即使使用内存顺序,这种优化也不会发生。

  1. 编译器是否允许移动语句上方acquire或下方的指令?
z …
Run Code Online (Sandbox Code Playgroud)

c++ atomic compiler-optimization memory-barriers instruction-reordering

10
推荐指数
1
解决办法
396
查看次数

Windows 中的 stdin、stdout 文件位于哪里?

每当我执行 C 程序时,都会有 3 个标准文件,stdin, stdout, stderr. 这些在 Linux 中映射到/proc/self/fd/0, /proc/self/fd/1, /proc/self/fd/2,它链接到/dev/pts/0我的电脑。这是伪终端,该进程向其输出并从中获取输入。

Windows 中与此等效的是什么?当我在 Windows 中执行相同的程序时,这些stdin, stdout,指向哪里?stderr

c windows stdin stdout file

7
推荐指数
1
解决办法
3244
查看次数

未解决的参考:JvmInline In kotlin playground

这是取自kotlin 官网的值类的精确代码片段。

interface I

@JvmInline
value class Foo(val i: Int) : I

fun asInline(f: Foo) {}
fun <T> asGeneric(x: T) {}
fun asInterface(i: I) {}
fun asNullable(i: Foo?) {}

fun <T> id(x: T): T = x

fun main() {
    val f = Foo(42) 
    
    asInline(f)    // unboxed: used as Foo itself
    asGeneric(f)   // boxed: used as generic type T
    asInterface(f) // boxed: used as type I
    asNullable(f)  // boxed: used as Foo?, which is different from Foo
    
    // below, …
Run Code Online (Sandbox Code Playgroud)

kotlin kotlin-inline-class

6
推荐指数
1
解决办法
847
查看次数

了解 C++ 中的顺序一致性栅栏

我正在阅读有关 C++ 中的内存顺序的内容。我可以很好地理解放松和获取-释放模型。但我正在努力解决顺序一致性问题。

如果我没记错的话,从cppreference来看,std::memory_order_seq_cst“操作”相当于:

  • 当操作为“加载”时,获取操作加上单个总订单。
  • 当操作为“存储”时,释放操作加上单个总订单。
  • 当操作为“读-修改-写”时,acq-rel 操作加上单个全序。

std::memory_order_seq_cst但‘栅栏’又是怎样的情况呢?它相当于其中的哪一个?

  • 获取栅栏加上单个总订单。
  • 释放栅栏加上单个总订单。
  • 一个 acq-rel 围栏加上一个总订单。

如果和上面其中之一是等价的,那另外两个呢?

据我所知,如果是情况 1(获取栅栏),编译器可以自由地将任何写操作从栅栏上方移动到栅栏下方。类似地,如果是情况 2(释放栅栏),编译器可以自由地将任何读取操作从栅栏下方移动到栅栏上方。最后,如果是情况 3(acq-rel 栅栏),则不允许编译器跨栅栏移动任何指令。它是否正确?

我仍然很困惑。以上说法可能不正确。有不对的地方请指正。

c++ memory-barriers stdatomic

6
推荐指数
1
解决办法
496
查看次数

kotlin 协程是如何在底层实现的?

Kotlin 协程是该语言的关键功能之一。我很好奇他们是如何实现的。所以我写了这个 kotlin 代码片段,

CoroutineScope(Dispatchers.IO).launch {
    someFun(6)  // A suspend fun with single int argument.
}  // Which is converted into a synthetic method with an extra argument of continuation type added at the end.
Run Code Online (Sandbox Code Playgroud)

然后将其编译为字节码,然后将其反编译为Java(在Android Studio中)。我懂了,

BuildersKt.launch$default(CoroutineScopeKt.CoroutineScope((CoroutineContext)Dispatchers.getIO()), (CoroutineContext)null, (CoroutineStart)null, (Function2)(new Function2((Continuation)null) {
   private CoroutineScope p$;
   Object L$0;
   int label;
            
   @Nullable
   public final Object invokeSuspend(@NotNull Object $result) {
      Object var3 = IntrinsicsKt.getCOROUTINE_SUSPENDED();
      CoroutineScope $this$launch;
      switch(this.label) {
      case 0:
         ResultKt.throwOnFailure($result);
         $this$launch = this.p$;
         MainActivity var10000 = MainActivity.this;
         this.L$0 = $this$launch;
         this.label …
Run Code Online (Sandbox Code Playgroud)

java kotlin kotlin-coroutines

5
推荐指数
1
解决办法
1522
查看次数

您能否将具有更严格内存排序的原子加载存储拆分为单独的宽松加载存储以及内存屏障指令?

下面是用于跨线程数据同步的获取-释放语义的简单示例。

// thread 1                                     // thread 2
data = 100;
flag.store(true, std::memory_order_release);
                                                while(!flag.load(std::memory_order_acquire));
                                                assert(data == 100);
Run Code Online (Sandbox Code Playgroud)

据我了解,这准确地表明了获取-释放内存顺序的使用,并且程序将按预期工作。

但如果我使用独立屏障会怎样?

// thread 1                                     // thread 2
data = 100;
std::atomic_thread_fence(std::memory_order_release);
flag.store(true, std::memory_order_relaxed);
                                                while(!flag.load(std::memory_order_relaxed))
                                                    std::atomic_thread_fence(std::memory_order_acquire);
                                                assert(data == 100);
Run Code Online (Sandbox Code Playgroud)

我一直认为这与第一个例子完全相同

但今天我在 CppCon 上观看了 Herb Sutter 的演讲(C++ and Beyond 2012:Herb Sutter - 原子武器)。在视频中的1:07:10 ,他举了一个例子来说明独立围栏的效果并不理想。看完后我很困惑。

例子是这样的:

   // thread 1                                     // thread 2
   widget *temp = new widget();
XX mb();  XXXXXXXXXXXXXXXXXXXXX  // a
   global = temp;
                                                   temp2 = global;
                                                XX mb();  XXXXXXXXXXXXXXXXXXXXX …
Run Code Online (Sandbox Code Playgroud)

c++ multithreading synchronization atomic memory-barriers

5
推荐指数
0
解决办法
146
查看次数

C++ 中无前缀字符串的编码是什么?

C++ 中无前缀字符串的编码是什么?例如,所有字符串文字在 Java 中都被解析并存储为 UTF-16,在 Python3 中则被解析为 UTF-8。我猜想 C++ 文字就是这种情况u8""。但我不清楚像 之类的普通文字""

以下代码的输出应该是什么?

#include <iostream>
#include <iomanip>

int main() {
    auto c = "Hello, World!";
    while(*c) {
        std::cout << std::hex << (unsigned int){*c++} << " ";
    }
}
Run Code Online (Sandbox Code Playgroud)

当我在我的机器上运行它时,它会给出以下输出:

48 65 6c 6c 6f 2c 20 57 6f 72 6c 64 21 
Run Code Online (Sandbox Code Playgroud)

但这有保证吗?字符串文字的 Cppreference 页面表示普通字符串文字中的字符来自翻译字符集,翻译字符集指出:

翻译字符集由以下元素组成:

  • 由 ISO/IEC 10646 命名的每个字符,由其唯一的 UCS 标量值标识,以及
  • 每个 UCS 标量值的不同字符,其中未分配命名字符。

从这个定义来看,翻译字符集似乎是指 Unicode(或其超集)。那么除了显性之外,""和之间没有区别吗?u8""

假设如果我希望我的字符串采用 EBCDIC 编码(只是作为练习),那么在 …

c++ string character-encoding string-literals

5
推荐指数
1
解决办法
310
查看次数

C++ 中 inline 关键字的旧含义是否已弃用?

inline在说明符的 cppreference 页面上,它说:

inline当在函数的decl-specifier-seq中使用说明符时,该说明符将该函数声明为内联函数

联函数具有以下属性:程序中
可以有多个内联函数的定义,只要每个定义出现在不同的翻译单元中并且所有定义都相同。
...

然后,稍微低一点,它说,

该关键字的最初目的inline是向优化器指示函数的内联替换优于函数调用。...

除了这一行之外,没有任何关于 的使用的参考inline。后一个含义inline在 C++ 标准中仍然有效吗?或者后一种形式是否比前一种形式被弃用?

如果后一种形式仍然有效,是否值得在现代编译器中使用它?我听说,即使是编译器做出内联决定,但使用inline关键字会稍微推动它。这是真的?对于这种情况,我应该inline在程序中使用关键字吗?

c++ inline inline-functions

5
推荐指数
1
解决办法
468
查看次数