小编Pet*_*des的帖子

29
推荐指数
3
解决办法
2万
查看次数

检查 char 数组中前导字符的最快方法是什么?

我的代码遇到了瓶颈,所以这个问题的主要问题是性能。

我有一个十六进制校验和,我想检查一个字符数组的前导零。这就是我正在做的:

bool starts_with (char* cksum_hex, int n_zero) {
  bool flag {true};
  for (int i=0; i<n_zero; ++i)
    flag &= (cksum_hex[i]=='0');
  return flag;
}
Run Code Online (Sandbox Code Playgroud)

如果cksum_hex有,则上述函数返回truen_zero前导零,。但是,对于我的应用程序,此功能非常昂贵(占总时间的 60%)。换句话说,它是我代码的瓶颈。所以我需要改进它。

我还检查了std::string::starts_with哪些在 C++20 中可用,我发现性能没有差异:

// I have to convert cksum to string
std::string cksum_hex_s (cksum_hex);
cksum_hex_s.starts_with("000");     // checking for 3 leading zeros
Run Code Online (Sandbox Code Playgroud)

有关我正在使用的更多信息 g++ -O3 -std=c++2a,我的 gcc 版本是 9.3.1。

问题

  • 检查 char 数组中前导字符的更快方法是什么?
  • 有没有更有效的方法来做到这一点 std::string::starts_with
  • 按位运算在这里有帮助吗?

c++ optimization performance c++20

29
推荐指数
4
解决办法
2007
查看次数

在 macOS 上,“is_always_lock_free”给出“true”,但“is_lock_free()”给出“false”,为什么?

我正在尝试 C++ 原子std::atomic<T>::is_always_lock_freestd::atomic<T>::is_lock_free.

我写了一个简单的结构体A,想知道 的原子版本是否A是无锁的:

#include <iostream>
#include <atomic>

using namespace std;

struct A {
  int x;
  int y;
  int z;
};

int main() {
  atomic<A> b;

  cout << boolalpha;
  cout << "b.is_always_lock_free = " << b.is_always_lock_free << endl;
  cout << "b.is_lock_free = " << b.is_lock_free() << endl;

  return 0;
}
Run Code Online (Sandbox Code Playgroud)

x86-64 Linux上,我用g++ 9.4.0和C++17编译它,输出正常:

b.is_always_lock_free = false
b.is_lock_free = false
Run Code Online (Sandbox Code Playgroud)

然而,我也在我的Mac(ARM64 )上用clang++ 16.0.0编译它,输出很奇怪:

b.is_always_lock_free = true …
Run Code Online (Sandbox Code Playgroud)

c++ macos clang lock-free stdatomic

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

x86 Assembly和yasm中immediates(方括号)的基本用法

假设我声明了以下内容:

section .bss
buffer    resb     1
Run Code Online (Sandbox Code Playgroud)

这些说明如下:

mov    al, 5                    ; mov-immediate
mov    [buffer], al             ; store
mov    bl, [buffer]             ; load
mov    cl, buffer               ; mov-immediate?
Run Code Online (Sandbox Code Playgroud)

我是否理解bl将包含值5,并且cl将包含变量的内存地址section .text

我对两者之间的差异感到困惑

  • 立即进入登记册,
  • 将寄存器移动到立即(进入的是什么,数据或地址?)和
  • 在没有括号的情况下立即移动到寄存器中
    • 例如,buffervsmov cl, buffer

更新:阅读回复后,我认为以下摘要是准确的:

假设声明mov cl, [buffer]存在于mov edi, array.我的理解是:

  • edi将第0个数组索引的内存地址放入mov byte [edi], 3.
  • add edi, 3 将VALUE 3放入数组的第0个索引中
  • 之后edi,mov al, [array]现在包含数组第3个索引的内存地址
  • al将DATA置于第零个索引中mov al, [array+3].
  • al将DATA放在第三个索引处mov [al], …

x86 assembly nasm memory-address yasm

28
推荐指数
3
解决办法
2万
查看次数

为什么memcmp比for循环检查快得多?

为什么memcmp(a, b, size)比这快得多:

for(i = 0; i < nelements; i++) {
    if a[i] != b[i] return 0;
}
return 1;
Run Code Online (Sandbox Code Playgroud)

memcmp是CPU指令还是什么?它必须非常深,因为我memcmp在循环中使用了大量的加速.

c optimization performance memcmp

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

为什么在x86上对自然对齐的变量进行整数赋值?

我一直在读这篇关于原子操作的文章,它提到了32位整数赋值在x86上是原子的,只要该变量是自然对齐的.

为什么自然对齐确保原子性?

c c++ concurrency x86 atomic

28
推荐指数
2
解决办法
5386
查看次数

什么是callq指令?

我有一个由工具生成的x86_64架构的gnu汇编程序代码,并且有以下指令:

movq %rsp, %rbp  
leaq str(%rip), %rdi
callq puts
movl $0, %eax
Run Code Online (Sandbox Code Playgroud)

我找不到关于"callq"指令的实际文档.

我查看了http://support.amd.com/TechDocs/24594.pdf,这是"AMD64架构程序员手册第3卷:通用和系统指令",但它们只描述了CALL近距离和远距离指令.

我查看了gnu汇编程序https://sourceware.org/binutils/docs/as/index.html的文档,但找不到详细说明它支持的说明部分.

我理解它是对函数的调用,但我想知道细节.我在哪里可以找到它们?

x86 assembly x86-64 att

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

AT&T语法中(%eax)的含义?

你不得不原谅我,我是x86装配和一般装配的新手.

所以我的问题是,我有类似的东西:

addl %edx,(%eax)
Run Code Online (Sandbox Code Playgroud)

%eax是一个寄存器,它包含一个指向某个整数的指针.我们称之为xp

这是否意味着它说:*xp = *xp + %edx?(%edx是整数)

我很困惑addl将存储结果的地方.如果%eax是指向int的指针,那么(%eax)应该是该int的实际值.因此,将addl存储的结果%edx+(%eax)*xp?我真的很想有人向我解释这个!

我非常感谢任何帮助!

x86 assembly addressing-mode

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

如何检查是否定义了固定宽度的整数

在 C++ 中,固定宽度整数被定义为optional,但我似乎无法找到推荐的方法来检查它们是否被实际定义。

检查固定宽度整数是否可用的便携式方法是什么?

c++ types cstdint stdint c++11

27
推荐指数
2
解决办法
1558
查看次数

C 和 C++ 结构体 ODR 规则差异的澄清

我知道 ODR、链接、static和如何extern "C"与函数配合使用。但我不确定类型的可见性,因为它们无法声明static,并且 C 中没有匿名名称空间。

特别是,我想知道以下代码如果编译为 C 和 C++ 的有效性

// A.{c,cpp}
typedef struct foo_t{
    int x;
    int y;
} Foo;

static int use_foo() 
{ 
    Foo f;
    f.x=5;
    return f.x;
}
Run Code Online (Sandbox Code Playgroud)
// B.{c,cpp}
typedef struct foo_t{
    double x;
} Foo;

static int use_foo() 
{ 
    Foo f;
    f.x=5.0;
    return f.x;// Cast on purpose
}
Run Code Online (Sandbox Code Playgroud)

使用以下两个命令(我知道两个编译器都会根据扩展自动检测语言,因此名称不同)。

  • g++ -std=c++17 -pedantic -Wall -Wextra a.cpp b.cpp
  • gcc -std=c11 -pedantic -Wall -Wextra a.c b.c

8.3 版本可以愉快地编译两者,没有任何错误。显然,如果两个结构符号都具有外部链接,则存在 ODR 违规,因为定义不相同。是的,编译器不需要报告它,因此我的问题是因为两者都没有报告。

它是有效的 C++ …

c c++ types linkage language-lawyer

27
推荐指数
2
解决办法
1781
查看次数