小编Jas*_* Yu的帖子

我可以直接对原子变量进行算术运算吗?

我可以直接对原子变量进行算术运算吗?

因为我发现 C 标准库提供了很多实用函数,例如atomic_fetch_add执行原子变量和非原子变量之间的加法。但是,我很好奇,由于变量是原子的,我可以直接对其进行算术运算吗?就像下面所示的代码一样:

#include <threads.h>
#include <stdio.h>
#include <stdatomic.h>
atomic_int i = 0;
int run(void* v) {
  i += 100;  // <- is this operaiton thread-safe?
  // atomic_fetch_add(&i, 100);
  printf("%d\n", i);
  return thrd_success;
}
int main(void) {
  thrd_t thread;  
  thrd_create(&thread, run, NULL);
  thrd_join(thread, NULL);
  return 0; 
} 
Run Code Online (Sandbox Code Playgroud)

c multithreading atomic language-lawyer stdatomic

12
推荐指数
2
解决办法
1260
查看次数

真实的CPU频率和C中的clock_t之间有什么关系?

真实的CPU频率和C语言中的clock_t(单位是时钟节拍)之间有什么关系?

假设我有下面一段 C 代码,它测量 CPU 运行循环所消耗的时间for
但由于 CLOCKS_PER_SEC 在 C 标准库中是一个常量值(基本上是 1000,000),我想知道该clock函数如何测量程序在具有不同 CPU 频率的不同计算机上运行时所消耗的实际 CPU 周期(对于我来说)笔记本电脑,它是 2.6GHz)。

如果它们不相关,CPU 计时器在上述场景中如何工作?

#include <time.h>
#include <stdio.h>
int main(void) {
  clock_t start_time = clock();    
  for(int i = 0; i < 10000; i++) {}
  clock_t end_time = clock();
  printf("%fs\n", (double)(end_time - start_time) / CLOCKS_PER_SEC); 
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

c posix clock cpu-cycles

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

WebAssembly 规范中的“块”和“循环”有什么区别?

正如标题所示,规范说“循环”是

开头带有标签的块,可用于形成循环。

对于“块”:

块构造的开头,末尾带有标签的指令序列。

但是在“ br ”(用于将分支切换到标记块)的帮助下,即使使用“块”,我也可以形成相同的控制结构,对吧?那么,这两个指令有什么区别呢?

webassembly

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

如何读取这段Rust代码的汇编代码?

我正在尝试阅读一段 Rust 汇编代码,但实际上,它比 C/C++ 编译器生成的 ASM 代码更难阅读。那么,如何分析下面这段Rust代码的ASM代码呢?

fn main() { 
    let closure = |x| println!("{}", x);
    let x: fn(x: i32) -> () = closure; 
    println!("{}", x as i32);
}
Run Code Online (Sandbox Code Playgroud)

相应的汇编代码如下所示,并带有一些注释(我只粘贴了主要部分,完整版本请使用此永久链接:https://play.rust-lang.org/ ?version=nightly&mode=release&edition=2018&gist=e7ba4844f1ce6e881912dc074152988d ):

playground::main: # @playground::main
# %bb.0:
    subq    $72, %rsp
    leaq    core::ops::function::FnOnce::call_once(%rip), %rax
    movl    %eax, 4(%rsp)
    leaq    4(%rsp), %rax
    movq    %rax, 8(%rsp)
    movq    core::fmt::num::imp::<impl core::fmt::Display for i32>::fmt@GOTPCREL(%rip), %rax
    movq    %rax, 16(%rsp)
    leaq    .L__unnamed_2(%rip), %rax  # the contents of rdx come from .L__unnamed_2(%rip), how to evaluate this part?
    movq    %rax, …
Run Code Online (Sandbox Code Playgroud)

assembly reverse-engineering x86-64 rust

2
推荐指数
1
解决办法
791
查看次数

关于尾调用优化的问题

据我所知,进行尾调用优化的一个前提是递归点应该是函数中的最后一句,并且递归调用的结果应该立即返回。但为什么?

以下是 TCO 的有效示例:

int factorial(int num) {
  if (num == 1 || num == 0)
    return 1;
  return num * factorial(num - 1);
}
Run Code Online (Sandbox Code Playgroud)

那么,有了这个规则,下面的代码是不是也可以优化呢?为什么不?

#include <stdio.h>
int factorial(int num) {
  if (num == 1 || num == 0)
    return 1;
  int temp = num * factorial(num - 1);
  printf("%d", temp);
  return temp;
}
Run Code Online (Sandbox Code Playgroud)

我想知道我应该如何向其他人解释为什么上述规则对于拥有 TCO 是必要的。但不仅仅是简单地跟随。

c tail-call-optimization

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

C中的短路评估没有被编译器反映

我试图通过 GCC 和 Clang 使用 -O3 优化标志编译下面的 C 代码,在查看生成的汇编代码后,我发现这些编译器都没有实现 &&运算符的C 标准中提到的短路评估。

您可以参考下面的汇编代码了解更多信息,foo 函数的前五行代码将按顺序运行,并且它会比较 && 运算符的两个操作数,这实际上违反了标准。那么,这里面有什么误会吗?

C代码:

#include <stdio.h>
#include <stdbool.h>
void foo(int x, int y) {
  bool logical = x && y;
  printf("%d", logical);
}
int main(void) {
  foo(1, 3);
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

生成的汇编代码:

foo:                                    # @foo
        test    edi, edi
        setne   al
        test    esi, esi
        setne   cl
        and     cl, al
        movzx   esi, cl
        mov     edi, offset .L.str
        xor     eax, eax
        jmp     printf                          # TAILCALL
main:                                   # @main
        push …
Run Code Online (Sandbox Code Playgroud)

c x86 gcc clang

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