公众号
RSS https://github.com/wanghenshui/cppweeklynews/releases.atom
欢迎投稿,推荐或自荐文章/软件/资源等
感谢不语
赞助
标准委员会动态/ide/编译器信息放在这里
编译器信息最新动态推荐关注hellogcc公众号 本周更新 2023-06-07 第205期
llvm weekly我可能也看一下,顺便展开讲讲。可能更新以后要挪到周六,周知一下
看内容多不多,不多就讲讲llvm weekly
另外视频压了很多没看。看视频最大的问题是关键信息提取太慢了,lighting talk能快一些,长视频突出一个铺垫拉满。
这周末我准备把2021的 lighting talk看一遍,周末可能发一下整理,或者下周发一下整理
本周最热闹的应该是这个问题 DeepMind AI 创造出比人类快 70% 的排序算法,会产生哪些影响?
实际上根据他的压测结果,没有70%这个结论。有点收益,但不是70%
代码去年就合入了
review链接 https://reviews.llvm.org/D118029
代码链接 https://github.com/llvm/llvm-project/commit/194d1965d2c841fa81e107d19e27fae1467e7f11
这个问题下大家在互相拉扯,我之前看到这个也是先入为主嘲讽一波,啊原来汇编17行,你优化了一下,16行了,AI可以了,收收味
不能说没进步,首先不是introspect sort改成pdqsort这种跨步收益(llvm已经是pdqsort了。gcc不是,想用可以用boost)
其次看benchmark https://github.com/wanghenshui/cppweeklynews/pull/53
有些场景甚至慢了。但前排都是提升的,基本%1。
不过其他答案给了个AI优化hash算法的。这个确实牛逼 https://github.com/abseil/abseil-cpp/commit/74eee2aff683cc7dcd2dbaa69b2c654596d8024e
我一直觉得hash算法这玩意不是人想的,AI感觉在这个方向能有更大收获
依赖输入的AI优化说实话有点像PGO
优化尚不明显,AI仍需努力
话说问问ChatGPT老师也能得到相同的结论 https://zhuanlan.zhihu.com/p/635847068
之前聊过这个http://0x80.pl/notesen/2023-04-09-faster-parse-ipv4.html
Daniel Lemire他也感兴趣,毕竟他写了个url解析库ada 仓库 https://github.com/ada-url/ada
需要这玩意。他根据上面这哥们的代码改了一版本,相比gcc,性能提升十倍
代码
https://github.com/lemire/Code-used-on-Daniel-Lemire-s-blog/blob/master/2023/06/08/src/sse_inet_aton.c
另外,文中提到的 simdzone 是dns zone文件解析库 代码 https://github.com/NLnetLabs/simdzone
说实话我一直没研究SIMD。感觉躲不开了。这里标记个TODO。早晚得研究下
一个很巧妙的办法让成员避免比较
比如一个类
struct A {
using allocator_type = std::pmr::polymorphic_allocator<std::byte>;
int data1;
int data2;
int data3;
allocator_type alloc;
A(int a, int b, int c, allocator_type d) : data1(a), data2(b), data3(c), alloc(d) {}
friend auto operator<=>(const A&, const A&) = default;
};
怎么实现<=>
能不比较alloc呢?
像咱这种笨比,就手写,不default,写成里面的来比较
比如
friend std::strong_ordering operator<=>(const A& lhs, const A& rhs) {
if (auto r = (lhs.data1 <=> rhs.data1); r != 0) {
return r;
} else if (auto r = (lhs.data2 <=> rhs.data2); r != 0) {
return r;
} else if (auto r = (lhs.data3 <=> rhs.data3); r != 0) {
return r;
} else {
return (1 <=> 1);
}
}
或者聪明一点,使用tie
friend std::strong_ordering operator<=>(const A& lhs, const A& rhs) {
auto tie = [](auto& x) { return std::tie(x.data1, x.data2, x.data3); };
return tie(lhs) <=> tie(rhs);
}
friend bool operator==(const A& lhs, const A& rhs) {
auto tie = [](auto& x) { return std::tie(x.data1, x.data2, x.data3); };
return tie(lhs) == tie(rhs);
}
但还是要手写,能不能default?
作者的办法
#include <compare>
#include <memory_resource>
#include <cassert>
struct ComparisonIgnorerBase {
using CIB = ComparisonIgnorerBase;
constexpr friend auto operator<=>(const CIB&, const CIB&) = default;
};
template<class T>
struct ComparisonIgnorer : ComparisonIgnorerBase {
T t_;
ComparisonIgnorer(T t) : t_(std::move(t)) {}
};
struct A {
using allocator_type = std::pmr::polymorphic_allocator<std::byte>;
int data1;
int data2;
int data3;
ComparisonIgnorer<allocator_type> alloc;
A(int a, int b, int c, allocator_type d) : data1(a), data2(b), data3(c), alloc(d) {}
friend auto operator<=>(const A&, const A&) = default;
};
int main() {
std::pmr::monotonic_buffer_resource mr1;
std::pmr::monotonic_buffer_resource mr2;
A a = {1,2,3, &mr1};
A b = {1,2,3, &mr2};
A c = {3,1,2, &mr1};
assert(a == b);
assert(a < c);
}
确实挺巧妙,不需要比较的成员,替他实现一个空的 <=>
鸠占鹊巢
看<程序员自我修养 链接装载库=""> 就行了。这个文章也是讲的那玩意程序员自我修养>
#include <span>
constexpr std::array a = {1, 2, 3, 4, 5};
constexpr std::span s{a};
static_assert(s[0]==a[0]);
看不懂
可读性问题,不是必要的operator() 不要用
struct StorageLoader
{
template<typename DataType>
DataType Load(StorageOptions<DataType> const* options);
template<typename DataType>
DataType operator()(StorageOptions<DataType> const* options)
{ return Load(options); }
};
// 1 Using function call operator
data1 = storageLoader(&data1Options);
// 2 Using named method
data1 = storageLoader.Load(&data1Options);
// 3 Named method works better for nullptr
data1 = storageLoader.Load<Data1>(nullptr);
第一种显然是不必要的
不必要的operator ()实现这玩意整花活没意义
repair_status repair::task_manager_module::get(int id) const {
if (std::cmp_greater(id, _sequence_number)) {
throw std::runtime_error(format("unknown repair id {}", id));
}
auto it = _status.find(id);
if (it == _status.end()) {
return repair_status::SUCCESSFUL;
} else {
return it->second;
}
}
std::cmp_greater 是c++20的,之前介绍过,语义是
-1 > 0u; // true
std::cmp_greater(-1, 0u); // false
跟着最新标准演进代码,收益还是非常明显的,起码不会写错
浮点数的精度问题
讲代码怎么写的,讲的挺好的 PPT在这里
https://github.com/mattgodbolt/correct-by-construction
感觉值得用中文讲一遍
想要演讲却不知道说啥?没有自信?这里有一堆指导视频教你做演讲
Andrei Alexandrescu的和Chandler Carruth 的演讲总是有意思,他们的演讲我一直都看。其他人说的哎也就那么回事
这个讲的是之前clang那个死循坏优化代码,UB介绍。已经介绍一万多遍了
介绍view的使用和一些bug,感觉之前说过类似的案例,比如range loop bug 迭代器边界问题等等。这个值得看一下,感觉今年cppcon还会讲一遍
如果有疑问评论最好在上面链接到评论区里评论,这样方便搜索,微信公众号有点封闭/知乎吞评论