当我搜索时,我发现 7 年前的结果谈论的是 clang 的叉子而不是 clang 本身。
使用 avr-gcc 我可以编译并上传我的代码
avr-gcc a.cpp -DF_CPU=16000000 -mmcu=atmega2560 -Wall -Werror -Wextra -Os
avr-objcopy -j .text -j .data -O ihex a.out my.hex
sudo avrdude -patmega2560 -cwiring -P/dev/ttyACM0 -b115200 -D -Uflash:w:my.hex:i
Run Code Online (Sandbox Code Playgroud)
我想用 替换第一步clang++。我在这里所做的更改
--target=avr-nostdlib因为我会自己添加它-I/usr/avr/include/因为路径不是隐式的-L/usr/avr/lib/avr6 -lc -latmega2560,因此它有足够的信息来构建精灵我在 /usr/lib/gcc/avr/10.2.0/device-specs/specs-atmega2560 找到了设备规格,其中提到crtatmega2560.o并且-latmega2560似乎位于/usr/avr/lib/avr6/. 所以我想出了以下内容并得到了这些错误。我应该如何编译才能使用 avrdude 获取十六进制上传?
$ clang++ a.cpp -DF_CPU=16000000 -mmcu=atmega2560 -Wall -Werror -Wextra -Os --target=avr -I/usr/avr/include/ -nostdlib -L/usr/avr/lib/avr6 …Run Code Online (Sandbox Code Playgroud) -Edit2- 似乎偶尔我的 CPU 运行未排序和排序一样快。在其他机器上,它们的速度始终相同。我想我没有正确地进行基准测试,或者幕后发生了微妙的事情
- 编辑 - 下面的 ASM 代码。生成的代码在主循环中是相同的。有人可以确认它是更快还是相同?我正在使用 clang 10 并且我在 ryzen 3600 上。根据编译器资源管理器,没有分支,添加使用 SIMD 指令,该指令根据掩码添加 A 或 B。掩码来自 >= 128 并且 B 是 0 的向量。所以不,我所看到的没有隐藏的分支。
我认为这个非常受欢迎的问题很愚蠢,并在 clang 中尝试过为什么处理排序数组比处理未排序数组更快?
使用 g++ -O2 需要 2 秒,clang 需要 0.32。我尝试使它像下面这样无分支,发现即使它是无分支排序仍然使它更快。这是怎么回事?!(似乎 O2 对代码进行了矢量化,所以我没有尝试做更多)
#include <algorithm>
#include <ctime>
#include <stdio.h>
int main()
{
// Generate data
const unsigned arraySize = 32768;
int data[arraySize];
for (unsigned c = 0; c < arraySize; ++c)
data[c] = std::rand() % 256;
// !!! With …Run Code Online (Sandbox Code Playgroud) 举个例子,如果我将图像上传到 imgur 两次,并在另一个网站上上传一次,则很可能所有 3 个图像都有不同的校验和。jpeg 是有损的,所以我不能简单地检查像素是否匹配。
如何检查同一张图片是否有不同的编码?我不想编写算法,我想通过 CLI 使用库或离线应用程序
附加信息:如果裁剪方式不同,我更喜欢将其视为不同的图片,但对于我的用例而言,这并不重要(如果我想要的话,我可以简单地检查宽度和高度?)
我为 InnerStruct 编写了一个漂亮的打印机,它将数组显示为 2 个元素和正确的值。我还为TestStruct2开了个玩笑,但是我不知道如何使TestStruct包含与InnerStruct相同的内容。我不知道如何从 gdb/python 访问 array.nestedVariables。我如何编写这个以便 TestStruct 给出与 InnerStruct 相同的结果?
来源
struct InnerStruct
{
int buffer[100];
int len;
};
struct TestStruct
{
InnerStruct array;
};
struct TestStruct2
{
InnerStruct array;
};
int main() {
TestStruct s;
s.array.buffer[0] = 5;
s.array.buffer[1] = 8;
s.array.len=2;
TestStruct2 s2;
s2.array.buffer[0] = 5;
s2.array.buffer[1] = 8;
s2.array.len=2;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
.gdbinit
python
pp = gdb.printing.RegexpCollectionPrettyPrinter("pp")
class InnerStructPrinter:
"Print a InnerStruct"
class _iterator:
def __init__ (self, start, finish):
self.item = start
self.finish = finish …Run Code Online (Sandbox Code Playgroud) 我正在查看有关 hello world 二进制大小的页面,我想知道如果我没有 lib c 我可以获得多小的二进制文件。我从一些非常简单的事情开始(代码如下)。正如你所看到的,我运气不佳,5 条指令仍然是 13K 的二进制文件。我究竟做错了什么?
$ cat nolib.c
void _start() {
asm("mov $60,%rax; mov $1,%rdi; syscall");
}
$ gcc -nostdlib nolib.c
$ strip a.out
$ ls -lh
-rwxr-xr-x 1 eric eric 13K Nov 21 18:03 a.out
Run Code Online (Sandbox Code Playgroud) 有_aligned_realloc的 linux 等价物吗?
我想使用 realloc 所以我不必每次调整数据时都对数据进行 memcpy。我被 mmap 卡住了吗?我只使用了一次 mmap 是否有推荐的方法来实现将调整几次大小的内存?我假设我不能将 mmap 与aligned_alloc 混合使用,并且我必须在第一次调整大小时执行memcpy?(或始终使用 mmap)
下面的 realloc 并不总是对齐。我在(64位)linux下使用gcc和clang进行了测试
#include<cstdlib>
#include<cstdio>
#define ALIGNSIZE 64
int main()
{
for(int i = 0; i<10; i++)
{
void *p = aligned_alloc(ALIGNSIZE, 4096);
void *p2 = realloc(p, 4096+2048); //This doesn't always align
//void *p3 = aligned_alloc(ALIGNSIZE, 4096/24); //Doesn't need this line to make it unaligned.
if (((long)p & (ALIGNSIZE-1)) != 0 || ((long)p2 & (ALIGNSIZE-1)) != 0)
printf("%d %d %d\n", i, ((long)p & …Run Code Online (Sandbox Code Playgroud) 我正在使用 clang++ 13.0.1
下面的代码可以工作,但显然很难看。我该如何写一个strlen?-编辑- 受到答案的启发,似乎我可以自己实现 strlen
#include <cstdio>
constexpr int test(const char*sz) {
if (sz[0] == 0)
return 0;
if (sz[1] == 0)
return 1;
if (sz[2] == 0)
return 2;
return -1;
//return strlen(sz);
}
constinit int c = test("Hi");
int main() {
printf("C %d\n", c);
}
Run Code Online (Sandbox Code Playgroud) 最初我尝试了 lzcnt 但似乎在 Mac 上不起作用。我正在与使用 Apple M1 CPU(ARM64v8.4)的人一起工作
在这个列出ARM 8的arm文档中,clz支持使用0
CLZ Xd、Xm
计数前导零(64 位):将 Xd 设置为 Xm 最高有效端的二进制零的数量。结果将在 0 到 64 范围内(含 0 和 64)。
我们最初支持的CPU是x86-64,它有_lzcnt_u64
如果值为 0,两条指令似乎都会返回 64。具体来说,ARM 上的“0 到 64包含在内”,英特尔网站也建议这样做(并由我的代码确认)
然而 GCC 说如下
内置函数:int __builtin_clzll (unsigned long long)
与 __builtin_clz 类似,但参数类型为 unsigned long long。
我可以安全地使用 0 还是这个内置函数使用不同的指令?我尝试了 clang,消毒剂停止了程序,并告诉我这是一个令我惊讶的问题。
如果我像这两条指令一样传入 0,那么当我想获得 64 时,我应该如何获得前导零计数
举个例子,假设我有一个名为File. 现在文件可以以二进制或文本形式打开。我的构造函数目前是File(const char*filename). 让我们假设 open 的实现是完全不同的二进制和文本。我到底要怎么构造这个?
我考虑过使用静态函数,但我不想返回指针。我可以传入一个指针,但我宁愿不允许在没有实际初始化的情况下构造一个类。
我正在考虑在构造函数中使用 enum 或 bool ,但对我来说感觉“错误”(以及我可能这样做的方式)。我可以为二进制和文本使用不同的类名,并且两者都继承基本实现(或其他实现),即使唯一的区别是构造函数。
在 C++ 中这样做最惯用的方法是什么?
像https://uops.info/和 Agner Fog 的指令表,甚至英特尔自己的手册这样的网站,都列出了相同指令的各种形式。例如add m, r(在 Agner 的表格中)或add (m64, r64)在 uops.info 上,或ADD r/m64, r64在英特尔的手册中(https://www.felixcloutier.com/x86/add)。
这是我在 Godbolt 上运行的一个简单示例
__thread int a;
void Test() {
a+=5;
}
Run Code Online (Sandbox Code Playgroud)
添加是add DWORD PTR fs:0xfffffffffffffffc,0x5。它以操作码开头64 83 04 25。
有几种方法可以编写我的真实代码,但我想查找这可能需要多少个周期以及其他信息。我怎么找到这个指令的参考?我尝试在https://uops.info/table.html 中输入“add”并检查我的架构。但我不知道哪个条目是正在使用的指令。
现在在这种特定情况下,我猜测操作码是Add m64, r64但我不知道fs:在地址之前使用是否有任何惩罚,或者是否有办法查看操作码,以便我可以确认我正在查看正确的参考
我特别希望我的变量之一没有构造函数和析构函数。它的定义是这样的
struct Dummy { ~Dummy() { assert(0); } };
__thread Dummy dumb;
Run Code Online (Sandbox Code Playgroud)
真正的代码是零初始化的,并从线程本地内存池中获取内存。该池在 main 末尾被销毁,因此该析构函数尝试访问已释放的内存池。
我可以解决这个问题,但我想以一种干净的方式做到这一点。1)我可以告诉编译器在所有线程本地(或全局)变量之后释放我的池吗?或者是否在所有线程本地函数之前对其进行初始化,以便在适当的时间进行清理?或者更好的是 2) 根本不执行清理?我本可以发誓__thread不允许构造函数/析构函数,所以我很惊讶这甚至运行了。
堆栈跟踪显示__run_exit_handlers是调用析构函数的函数。它的父母是exit, __libc_start_main并且start。这在 clang 和 gcc 上都会发生
我正在寻找类似的东西(下面是C)
void MyFunction() {
//Do work
static int serial;
++serial;
printf("Function run #%d\n", serial);
//Do more work
}
Run Code Online (Sandbox Code Playgroud)