Skip to content

Commit 75c7e9a

Browse files
authored
183 (#179)
* posts/template.md * fix #177 #176 * udpate
1 parent 832ada1 commit 75c7e9a

3 files changed

Lines changed: 213 additions & 2 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ RSS使用仓库的release RSS [链接](https://github.com/wanghenshui/cppweeklyn
3434

3535
## 2025
3636

37-
| [181](./posts/181.md) | [182](./posts/182.md) | | | | | | | | |
37+
| [181](./posts/181.md) | [182](./posts/182.md) | [183](./posts/183.md) | | | | | | | |
3838
| ------------------ | ------------------ | ------------------ | ------------------ | ------------------ | ------------------ | ------------------ | ------------------ | ------------------ | ------------------ |
3939
| | | | | [175](./posts/175.md) | [176](./posts/176.md) | [177](./posts/177.md) | [178](./posts/178.md) |[179](./posts/179.md) | [180](./posts/180.md) |
4040
| | | | | | | | | | |

posts/183.md

Lines changed: 211 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,211 @@
1+
---
2+
layout: post
3+
title: 第183期
4+
---
5+
# C++ 中文周刊 2025-05-19 第183期
6+
7+
8+
[周刊项目地址](https://github.com/wanghenshui/cppweeklynews)
9+
10+
公众号
11+
12+
<img src="https://wanghenshui.github.io/cppweeklynews/assets/code.png" alt="" width="30%">
13+
14+
点击「查看原文」跳转到 GitHub 上对应文件,链接就可以点击了
15+
16+
qq群 753792291 答疑在这里
17+
18+
[RSS](https://github.com/wanghenshui/cppweeklynews/releases.atom)
19+
20+
欢迎投稿,推荐或自荐文章/软件/资源等,评论区留言
21+
22+
23+
---
24+
25+
## 资讯
26+
27+
标准委员会动态/ide/编译器信息放在这里
28+
29+
[编译器信息最新动态推荐关注hellogcc公众号 本周更新 2025-01-08 第288期](https://mp.weixin.qq.com/s/jMaR7QyCD40uCAKJSyLw6A)
30+
31+
[性能周刊](https://mp.weixin.qq.com/s/rkoBXmzhrbhvN4AEmBHS7w)
32+
33+
34+
## 文章
35+
36+
### [C++26: constexpr exceptions](https://www.sandordargo.com/blog/2025/05/07/cpp26-constexpr-exceptions)
37+
38+
39+
优化异常constexpr化,不能constexpr的编译期报错,加固代码降低UB,同时降低异常开销,好事
40+
41+
### [C++20 concepts for nicer compiler errors](https://lemire.me/blog/2025/05/03/c20-concepts-for-nicer-compiler-errors/)
42+
43+
concept编译模版报错更易懂
44+
45+
### [An option(al) to surprise you](https://andreasfertig.com/blog/2025/05/an-optional-to-surprise-you/)
46+
47+
```cpp
48+
enum class State {
49+
Initial,
50+
WaitingForInput,
51+
GotValidInput,
52+
GotValidInputWithData,
53+
GotInvalidInput
54+
};
55+
56+
std::optional<const char*> Worker(State s, const char* data) {
57+
switch(s) {
58+
using enum State;
59+
case Initial: return std::nullopt;
60+
case WaitingForInput: return {};
61+
case GotValidInput: [[fallthrough]];
62+
case GotValidInputWithData: return data;
63+
case GotInvalidInput: return "";
64+
}
65+
66+
return std::nullopt;
67+
}
68+
```
69+
70+
幽默代码 这个例子里 optional有点类似optinal<T*> 存指针也就有可能存nullptr,导致误用报错。坏实践
71+
72+
73+
### [如何算闰年](https://hueffner.de/falk/blog/a-leap-year-check-in-three-instructions.html)
74+
75+
传统算法
76+
```c++
77+
bool is_leap_year(uint32_t y) {
78+
if ((y % 4) != 0) return false;
79+
if ((y % 100) != 0) return true;
80+
if ((y % 400) == 0) return true;
81+
return false;
82+
}
83+
```
84+
85+
显然,能继续优化
86+
```c++
87+
bool is_leap_year1(uint32_t y) {
88+
if ((y % 4) != 0) return false;
89+
if ((y % 25) != 0) return true;
90+
if ((y % 16) == 0) return true;
91+
return false;
92+
}
93+
```
94+
95+
我们考虑去掉mod
96+
```c++
97+
bool is_leap_year2(uint32_t y) {
98+
if ((y & 3) != 0) return false;
99+
if (y * 3264175145u > 171798691u) return true;
100+
if ((y & 15) == 0) return true;
101+
return false;
102+
}
103+
```
104+
105+
第二行有点令人费解 我们考虑通过定点缩放来去掉mod
106+
107+
我们需要找到一个分数来近似表示 1/25
108+
109+
在32位无符号整数中,我们可以用 m/2^32 来近似 1/25
110+
111+
通过计算得知 2^32 / 25 = 171798691.84
112+
所以我们取 m = 171798692 作为近似值
113+
因此,对于任意数x:
114+
115+
(x * 171798692) / 2^32 近似等于 x/25
116+
如果x是25的倍数,则结果是一个整数
117+
如果x不是25的倍数,则结果有小数部分
118+
在32位计算中,乘法 x * 171798692 的高32位实际上就是 (x * 171798692) / 2^32
119+
120+
要检查x是否为25的倍数,我们需要判断这个结果是否为整数,但实际上我们要的是相反的结果(不是25的倍数)
121+
122+
通过将问题转化为检查 x * 3264175145u > 171798691u,我们实际上在检查:
123+
124+
3264175145是2^32 - 171798692 + 1的补码
125+
这个比较操作效果上等同于检查x不是25的倍数
126+
为什么用3264175145而不是171798692?
127+
128+
这里的关键是编译器优化中使用的技巧。不是直接计算 x * 171798692 / 2^32,而是通过计算 x * (2^32 - 1) / 25 + 1 来达到同样的效果。
129+
130+
具体计算:
131+
(2^32 - 1) / 25 = 171798691.96
132+
取近似值为3264175145
133+
当我们用x乘以这个数时,对于25的倍数,结果恰好落在某个特定范围内,使得 x * 3264175145u > 171798691u 正好对应 x % 25 != 0
134+
135+
但是这种编译器也能优化,属于过度优化,我们考虑分支优化
136+
137+
```cpp
138+
bool is_leap_year3(uint32_t y) {
139+
return !(y & ((y % 25) ? 3 : 15));
140+
}
141+
```
142+
143+
性能比上面的要好
144+
145+
146+
作者考虑第二种算术优化和分支优化的结合版本
147+
148+
作者是用求解器硬算的,考虑构造 ((y * f) & m) <= t格式,然后求解器算出满足条件的f m t
149+
150+
```python
151+
import z3
152+
153+
BITS = 32
154+
f, m, t, y = z3.BitVecs('f m t y', BITS)
155+
156+
def target(y):
157+
return z3.And((y & 3) == 0, z3.Or(z3.URem(y, 25) != 0, (y & 15) == 0))
158+
159+
def candidate(x):
160+
return z3.ULE((x * f) & m, t)
161+
162+
solver = z3.Solver()
163+
solver.add(z3.ForAll(y, z3.Implies(z3.ULE(y, 400),
164+
candidate(y) == target(y))))
165+
166+
if solver.check() == z3.sat:
167+
print(f'found solution: {solver.model()}')
168+
else:
169+
print('no solution found')
170+
```
171+
172+
### [The case of the UI thread that hung in a kernel call](https://devblogs.microsoft.com/oldnewthing/20250411-00/?p=111066)
173+
174+
不要在进程内挂起线程。自己给自己搞死锁。感谢 YexuanXiao投稿
175+
176+
### [Load-store conflicts](https://zeux.io/2025/05/03/load-store-conflicts/)
177+
178+
非常好的文章 多版本编译器压测对比才发现问题所在
179+
180+
数据存在存储加载冲突,导致性能瓶颈,这种通过汇编是看不出来的,得对比压测才能看出来
181+
182+
## 视频
183+
184+
### [File IO - Past, Present and Future - Guy Davidson - ACCU 2024 ](https://www.youtube.com/watch?v=fNwVRGnM3Ls&list=PL9hrFapz4dsMFj78AiNheJV2tFBgK_FbC&index=18)
185+
186+
大部份都在讲历史,然后讲一段#embed 和提案相关的file handle之类的设计
187+
188+
### [Understanding the Filter View to Use It Right - Nicolai M. Josuttis - ACCU 2024 ](https://www.youtube.com/watch?v=jR3WE-hAhCc&list=PL9hrFapz4dsMFj78AiNheJV2tFBgK_FbC&index=12)
189+
190+
filter view由于缓存性质多了很多坑,主要是讲使用细节
191+
192+
### [Narrow Contracts and noexcept are Inherently Incompatible in C++ - John Lakos - ACCU 2024 ](https://www.youtube.com/watch?v=VCwC1cvP8i0&list=PL9hrFapz4dsMFj78AiNheJV2tFBgK_FbC&index=10)
193+
194+
Narrow contract和noexcept不兼容
195+
196+
什么?你不知道narrow contract是什么?翻出contract概念复习一下
197+
198+
## 开源项目介绍
199+
200+
- [asteria](https://github.com/lhmouse/asteria) 一个脚本语言,可嵌入,长期找人,希望胖友们帮帮忙,也可以加群753302367和作者对线
201+
202+
203+
204+
## 互动环节
205+
206+
---
207+
208+
[上一期](https://wanghenshui.github.io/cppweeklynews/posts/182.html)
209+
210+
[本期](https://wanghenshui.github.io/cppweeklynews/posts/183.html)
211+

posts/template.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ title: 第NNN期
1414

1515
点击「查看原文」跳转到 GitHub 上对应文件,链接就可以点击了
1616

17-
qq群 [点击进入](https://qm.qq.com/q/6NGizNPyG4) 满了加这个 729240657
17+
qq群 753792291 答疑在这里
1818

1919
[RSS](https://github.com/wanghenshui/cppweeklynews/releases.atom)
2020

0 commit comments

Comments
 (0)