在大多数处理器中,为什么L1缓存的大小小于L2缓存的大小?
我的代码遇到了瓶颈,所以这个问题的主要问题是性能。
我有一个十六进制校验和,我想检查一个字符数组的前导零。这就是我正在做的:
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。
std::string::starts_with?我正在尝试 C++ 原子std::atomic<T>::is_always_lock_free和std::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) 假设我声明了以下内容:
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], …为什么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在循环中使用了大量的加速.
我有一个由工具生成的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装配和一般装配的新手.
所以我的问题是,我有类似的东西:
addl %edx,(%eax)
Run Code Online (Sandbox Code Playgroud)
%eax是一个寄存器,它包含一个指向某个整数的指针.我们称之为xp
这是否意味着它说:*xp = *xp + %edx?(%edx是整数)
我很困惑addl将存储结果的地方.如果%eax是指向int的指针,那么(%eax)应该是该int的实际值.因此,将addl存储的结果%edx+(%eax)中*xp?我真的很想有人向我解释这个!
我非常感谢任何帮助!
在 C++ 中,固定宽度整数被定义为optional,但我似乎无法找到推荐的方法来检查它们是否被实际定义。
检查固定宽度整数是否可用的便携式方法是什么?
我知道 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.cppgcc -std=c11 -pedantic -Wall -Wextra a.c b.c8.3 版本可以愉快地编译两者,没有任何错误。显然,如果两个结构符号都具有外部链接,则存在 ODR 违规,因为定义不相同。是的,编译器不需要报告它,因此我的问题是因为两者都没有报告。