C++ 中文周刊 第141期

周刊项目地址

公众号

qq群 手机qq点击进入

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

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

提交 issue

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

本周内容比较少

本期文章由 黄亮Anthony HNY 赞助


资讯

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

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

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

文章

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

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

可能会有性能衰退

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

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

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

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

stream就是垃圾 strstream没人用。有spanstream代替

lemire博士新活

常规

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加速

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来处理

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给了个更快的

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 感兴趣可以玩一玩

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

直接把字符串当成int来算

#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 工作日开始更新视频了,这周好玩的列一下

这个作者danlark在llvm比较活跃

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

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

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


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实现都是错的

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

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

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

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之类的玩意,把数据导出 回调交给别的组件

不知道什么场景能用上

有意思的项目

招聘

字节的音视频团队,主要负责剪映上的音视频/非线性编辑相关工作,业务前景也比较好,目前有三个方向的岗位

base北上广深杭都可以,薪资open,有兴趣的同学可以通过链接投递

英伟达招llvm实习生

https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite/job/China-Shanghai/Software-Intern–LLVM-Compiler-Optimization_JR1976102

联系方式 vwei@nvidia.com

或微信 aoewqf1997 (请备注“LLVM实习生”

互动环节

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

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

看到这里或许你有建议或者疑问或者指出错误,请留言评论! 多谢! 你的评论非常重要!也可以帮忙点赞收藏转发!多谢支持! 觉得写的不错那就给点吧, 在线乞讨 微信转账