你有一个充满平衡和重量的房间.每个天平重10磅,当左侧和右侧的重量总和完全相同时,被认为是完美平衡的.您已在某些余额上放置了一些权重,并且您已将一些余额放在其他余额上.给出关于如何安排天平以及每个天平上多少额外重量的描述,确定如何增加天平的重量以使它们完全平衡.
平衡一切可能有多种方法,但总是选择在最低余额上增加额外重量的方式.
输入文件将以单个整数N开头,指定有多少余额.余额0由第1行和第2行指定,余额1由第3行和第4行指定等等.每对行的格式如下:
WL <balances>
WR <balances>
Run Code Online (Sandbox Code Playgroud)
WL和WR分别表示添加到左侧和右侧的重量.是一个以空格分隔的列表,其中包含此余额的另一侧余额.可能包含零个或多个元素.
考虑以下输入:
4
0 1
0 2
0
0 3
3
0
0
0
Balance 0 has balance 1 on its left side and balance 2 on its right side
Balance 1 has balance 3 on its right side
Balance 2 has three pounds on its left side
Balance 3 has nothing on it
Run Code Online (Sandbox Code Playgroud)
由于天平3没有任何东西,它已经完全平衡,重量总共10磅.平衡2没有其他平衡,所以我们需要做的就是通过在右侧放三磅来平衡它.现在重达16磅.平衡1右侧有三个平衡重,重10磅,所以我们只在左侧放10磅.Balance 1的重量总共为30磅.平衡0在其左侧(30磅)具有平衡1,在其右侧(16磅)具有平衡2,我们可以通过向右侧增加14磅来平衡它.
输出应为N行长,第n行列出添加到第n个余额的权重,格式如下:
<index>: <weight added to left side> <weight added to right side>
Run Code Online (Sandbox Code Playgroud)
所以这个问题的输出将是:
0: 0 14
1: …Run Code Online (Sandbox Code Playgroud) 函数的返回值通常存储在堆栈或寄存器中.但对于大型结构,它必须在堆栈上.在这个代码的真实编译器中必须进行多少复制?还是优化了?
例如:
struct Data {
unsigned values[256];
};
Data createData()
{
Data data;
// initialize data values...
return data;
}
Run Code Online (Sandbox Code Playgroud)
(假设函数无法内联..)
c compiler-theory abi calling-convention compiler-optimization
"最佳"意味着最少的指令(或最少的uops,如果任何指令解码到多个uop).机器码大小(以字节为单位)是相同insn计数的平局.
恒定生成本质上是一个新的依赖链的开始,所以延迟很重要.在循环内生成常量也很不寻常,因此吞吐量和执行端口需求也几乎无关紧要.
生成常量而不是加载它们需要更多指令(除了全零或全一),因此它会占用宝贵的uop-cache空间.这可能是比数据缓存更有限的资源.
Agner Fog优秀的优化装配指南涵盖了这一点Section 13.4.表13.10具有用于产生向量序列,每一个元素是0,1,2,3,4,-1,或-2,与从8位到64位单元大小.表13.11具有用于产生一些浮点值序列(0.0,0.5,1.0,1.5,2.0,-2.0,和位掩码为符号位.)
Agner Fog的序列仅使用SSE2,无论是设计还是因为它尚未更新一段时间.
使用短的非显而易见的指令序列可以生成哪些其他常量? (具有不同移位计数的进一步扩展是显而易见的而不是"有趣的".)是否有更好的序列用于生成Agner Fog列出的常量?
如何将128位immediates移动到XMM寄存器说明了将任意128b常量放入指令流的一些方法,但这通常是不合理的(它不会节省任何空间,并占用大量的uop-cache空间.)
在以下 C 代码中:
#include <stdio.h>
int main(void){getchar();}
Run Code Online (Sandbox Code Playgroud)
它产生以下汇编:
main:
push rbp
mov rbp, rsp
# no extra instruction here when header is included
call getchar
mov eax, 0
pop rbp
ret
Run Code Online (Sandbox Code Playgroud)
但是,如果我不包含stdio.h在文件中,那么它仍然可以编译,但会添加看起来像随机mov eax, 0指令的内容:
这是编译器资源管理器:https : //godbolt.org/z/3fTcss。这只是“未定义行为”的一部分,还是有特殊原因将之前的指令call getchar添加到那里?
引入int uncaught_exceptions() noexcept;inC++17而不是bool uncaught_exception() noexcept;引发了一个问题:是否可以同时出现多个异常。
返回值
- 当前线程中未捕获的异常对象的数量。
我试着想象这样一种情况,当它不止一个时。
绞尽脑汁后,我只想到了一个想法:在同一个块内的局部变量throw中放置一些东西。destructortry
但还是不行。
首先,它违反了强加于 s 的规则,destructor迫使他们这样做noexcept。其次,它可以通过 纠正noexcept(false),但它只会跟注terminate而不是在区块中结束catch。
所以它并不能解决问题。
最后,在catch方块内扔任何东西都是很常见的,没有什么不寻常的。因为一旦进入该catch块,uncaught_exceptions()就会递减并变为零。
所以我想知道是否有可能想象出这样一种情况,其中uncaught_exceptions()返回的值会超过1?
以下代码生成的程序集在使用-O3. 为了完整起见,代码始终在 GCC 13.2 中执行 SIMD,而从不在 clang 17.0.1 中执行 SIMD。
#include <array>
__attribute__((noinline)) void fn(std::array<int, 4>& lhs, const std::array<int, 4>& rhs)
{
for (std::size_t idx = 0; idx != 4; ++idx) {
lhs[idx] = lhs[idx] + rhs[idx];
}
}
Run Code Online (Sandbox Code Playgroud)
这是Godbolt 中的链接。
这是 GCC 12.3 的实际汇编(使用 -O3):
fn(std::array<int, 4ul>&, std::array<int, 4ul> const&):
lea rdx, [rsi+4]
mov rax, rdi
sub rax, rdx
cmp rax, 8
jbe .L2
movdqu xmm0, XMMWORD PTR [rsi]
movdqu xmm1, XMMWORD PTR [rdi]
paddd …Run Code Online (Sandbox Code Playgroud) 在C语言中,什么是十六进制数字字符串转换成二进制最有效的方法unsigned int还是unsigned long?
例如,如果我有0xFFFFFFFE,我想要一个intbase10值4294967294.
gcc是否支持amd64上的128位int?
如何定义?
如何使用scanf/printf进行读/写?
我一直看到人们声称MOV指令可以在x86中免费,因为寄存器重命名.
对于我的生活,我无法在一个测试用例中验证这一点.每个测试用例我尝试揭穿它.
例如,这是我用Visual C++编译的代码:
#include <limits.h>
#include <stdio.h>
#include <time.h>
int main(void)
{
unsigned int k, l, j;
clock_t tstart = clock();
for (k = 0, j = 0, l = 0; j < UINT_MAX; ++j)
{
++k;
k = j; // <-- comment out this line to remove the MOV instruction
l += j;
}
fprintf(stderr, "%d ms\n", (int)((clock() - tstart) * 1000 / CLOCKS_PER_SEC));
fflush(stderr);
return (int)(k + j + l);
}
Run Code Online (Sandbox Code Playgroud)
这为循环生成以下汇编代码(随意生成这个你想要的;你显然不需要Visual C++):
LOOP:
add edi,esi
mov …Run Code Online (Sandbox Code Playgroud) 当施放双无穷大时,反之亦然,它仍然是无穷大吗?和 NaN 一样吗?