前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C++ 中文周刊 第141期

C++ 中文周刊 第141期

作者头像
王很水
发布2024-07-30 14:45:18
720
发布2024-07-30 14:45:18
举报
文章被收录于专栏:C++ 动态新闻推送

周刊项目地址 https://github.com/wanghenshui/cppweeklynews

RSS https://github.com/wanghenshui/cppweeklynews/releases.atom

欢迎投稿,推荐或自荐文章/软件/资源等

请提交 issue https://github.com/wanghenshui/cppweeklynews/issues

最近在找工作准备面试题,更新可能有些拖沓,见谅

本期文章由 黄亮Anthony HNY 赞助

资讯

标准委员会动态/ide/编译器信息放在这里

clion新增AI助手 https://www.jetbrains.com/clion/whatsnew/

编译器信息最新动态推荐关注hellogcc公众号 OSDT Weekly 2023-12-06 第231期

文章

  • • 现代C++语言核心特性解析C++23标准补充 - 免费电子书 https://zhuanlan.zhihu.com/p/670502105

感兴趣的可以看一下。很短

  • • Outline: 代码分离编译优化 https://zhuanlan.zhihu.com/p/669417318

抽出相同的二进制,节省二进制大小。和inline逻辑相反

可能会有性能衰退

原理?如何找出重复的二进制序列?后缀树爆搜

也可以从不同角度来做,比如IR层

具体很细节。感兴趣的可以看看

  • • HotColdSplitting: 代码分离之性能优化 https://zhuanlan.zhihu.com/p/670400568

借助outline做冷热分离,有性能提升,还挺有意思的,算是PGO一部分吧,拿到profile来分析

  • • For processing strings, streams in C++ can be slow https://lemire.me/blog/2023/10/19/for-processing-strings-streams-in-c-can-be-slow/

stream就是垃圾 strstream没人用。感觉后面会演进个spanstream出来

  • • Parsing 8-bit integers quickly https://lemire.me/blog/2023/11/28/parsing-8-bit-integers-quickly/

lamire博士新活

常规

代码语言:javascript
复制
int parse_uint8_naive(const char *str, size_t len, uint8_t *num) {
  uint32_t n = 0;
  for (size_t i = 0, r = len & 0x3; i < r; i++) {
    uint8_t d = (uint8_t)(str[i] - '0');
    if (d > 9)
     return 0;
    n = n * 10 + d;
  }
  *num = (uint8_t)n;
  return n < 256 && len && len < 4;
}

当然c++可以用from chars加速

代码语言:javascript
复制
int parse_uint8_fromchars(const char *str, size_t len, uint8_t *num) {
  auto [p, ec] = std::from_chars(str, str + len, *num);
  return (ec == std::errc());
}

能不能更快?这是u8场景,考虑SWAR,组成一个int来处理

代码语言:javascript
复制
int parse_uint8_fastswar(const char *str, size_t len, 
    uint8_t *num) {
  if(len == 0 || len > 3) { return 0; }
  union { uint8_t as_str[4]; uint32_t as_int; } digits;
  memcpy(&digits.as_int, str, sizeof(digits));
  digits.as_int ^= 0x30303030lu;
  digits.as_int <<= ((4 - len) * 8);
  uint32_t all_digits = 
    ((digits.as_int | (0x06060606 + digits.as_int)) & 0xF0F0F0F0) 
       == 0;
  *num = (uint8_t)((0x640a01 * digits.as_int) >> 24);
  return all_digits 
   & ((__builtin_bswap32(digits.as_int) <= 0x020505));
}

评论区bob给了个更快的

代码语言:javascript
复制
int parse_uint8_fastswar_bob(const char *str, size_t len, uint8_t *num) {
  union { uint8_t as_str[4]; uint32_t as_int; } digits;
  memcpy(&digits.as_int, str, sizeof(digits));
  digits.as_int ^= 0x303030lu;
  digits.as_int <<= (len ^ 3) * 8;
  *num = (uint8_t)((0x640a01 * digits.as_int) >> 16);
  return ((((digits.as_int + 0x767676) | digits.as_int) & 0x808080) == 0) 
   && ((len ^ 3) < 3) 
   && __builtin_bswap32(digits.as_int) <= 0x020505ff;
}

压测代码在这里 https://github.com/lemire/Code-used-on-Daniel-Lemire-s-blog/tree/master/2023/11/28 感兴趣可以玩一玩

  • • Nerd Snipe: Small Integer Parsing https://blog.loadzero.com/blog/parse-int-nerdsnipe/

场景 完美hash,4bytes字符串做key,如何快速算hash?

直接把字符串当成int来算

代码语言:javascript
复制
#define SIZE 512
uint8_t lut[SIZE] = {};

// multiply, shift, mask
uint32_t simple_hash(uint32_t u) {
    uint64_t h = (uint64_t) u * 0x43ff9fb13510940a;
    h = (h >> 32) % SIZE;
    return (uint32_t) h;
}

// generate, cast and hash
void build_lut() {
    char strings[256*4];
    memset(strings, 0, sizeof(strings));
    char *iter = strings;
    for (int i = 0; i < 256; ++i) {
        sprintf(iter, "%d", i);
        iter += 4;
    }

    iter = strings;
    for (int i = 0; i < 256; ++i) {
        unsigned c = *(unsigned*) iter;
        iter += 4;
        unsigned idx = simple_hash(c);
        lut[idx] = i;
    }
}

视频

cppcon2023 工作日开始更新视频了,这周好玩的列一下

  • • A Long Journey of Changing std::sort Implementation at Scale - Danila Kutenin - CppCon 2023 https://www.youtube.com/watch?v=cMRyQkrjEeI

这个作者danlark在llvm比较活跃

这个视频非常值得一看,列举了sort的改进优化,各个系统的差异,以及nth_element的副作用问题

很多库写的median算法实际是错的!

https://godbolt.org/z/9xWoYTfMP

代码语言:javascript
复制

int median(std::vector<int>& v) {
   int mid = v.size() / 2;
   std::nth_element(v.begin(), v.begin() + mid, v.end());
   int result = v[mid];
   if (v.size() % 2 == 0) {
     std::nth_element(v.begin(), v.begin() + mid - 1, v.end());
     result = (v[mid] + v[mid-1])/2;  
     // result = (result + v[mid-1]) /2;
   }
   return result;
}

由于nth_element不保证整体有序,只保证n的位置是对的,所以第二次的计算可能改变第一次的结果

然而社区很多median实现都是错的

  • • Customization Methods: Connecting User and C++ Library Code - Inbal Levi - CppCon 2023 https://www.youtube.com/watch?v=mdh9GLWXWyY

介绍了一些查找逻辑的设计,从swap到ADL,到CPO tag_invoke 再到最近的讨论,有Custom function设计

还算有意思 。但有句讲句tag_invoke很扭曲,cpo也是

  • • Variable Monitoring with Declarative Interfaces - Nikolaj Fogh - Meeting C++ 2023 https://www.youtube.com/watch?v=AJDbu1kaj5g

介绍一个库 https://github.com/nfogh/monitoring/

代码语言:javascript
复制
auto myMonitor = Monitor([](int i){ return i > 0; }, [](bool valid){ std::cout << "Valid: " << valid << std::endl; }]);
int variable = 0;
myMonitor(variable); // Prints Valid: 0
variable = 1;
myMonitor(variable); // Prints Valid: 1

不过不知道有啥用途。signal handler类似的玩意

比如监控内存,真到了瓶颈,直接在发现的位置条件判断也不是不行

或者类似bvar之类的玩意,把数据导出 回调交给别的组件

不知道什么场景能用上

有意思的项目

  • • https://github.com/sunxfancy/vscode-llvm 在vscode里拿到llvm compiler explore类似的效果。检查IR,查看CFG之类的,很厉害
  • • asteria https://github.com/lhmouse/asteria 一个脚本语言,可嵌入,长期找人,希望胖友们帮帮忙,也可以加群753302367和作者对线 (原来的群被举报了)
  • • Unilang https://github.com/linuxdeepin/unilang deepin的一个通用编程语言,点子有点意思,也缺人,感兴趣的可以github讨论区或者deepin论坛看一看。这里也挂着长期推荐了
  • • https://gitee.com/okstar-org/ok-edu-desktop 一个IM通信软件,做IM的可以关注,现在正在做全面整合阶段,开始组建商业团队阶段,年底开始融资,你参加了就快发财了,会的快来

互动环节

公众号终于收到了广告,不容易,预计19号发,挂一周。提前预告一下,大家别生气

最近面了好多工作,真有点迷茫了自己未来要做什么,年前就休息吧。随便看看了

引用链接

[1] vwei@nvidia.com: mailto:vwei@nvidia.com

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2023-12-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 CPP每周推送 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 资讯
  • 文章
  • 视频
  • 有意思的项目
  • 互动环节
    • 引用链接
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档