工程
2026
从 RVO 到 Guaranteed Copy Elision:C++ 返回值优化的演进
·4193 字·9 分钟
一道我答错的题 # 最近做了一个 Modern C++ 水平测试,碰到这样一道题:
1#include <utility> 2 3struct Widget { 4 Widget() = default; 5 Widget(const Widget&) = delete; 6 Widget(Widget&&) = delete; 7}; 8 9Widget createA() { return Widget{}; } 10 11Widget createB() { 12 Widget w; 13 return w; 14} 15 16Widget createC() { 17 Widget w; 18 return std::move(w); 19} 问:在 C++17 下,哪些函数能通过编译?
当数字 1 键失灵之后:从 XWayland 假象到 Linux 内核输入子系统(evdev/uinput)
起因 # 昨晚把常用的 87 配列机械键盘拆开清洗了一遍。装回去之后发现主键盘区的数字 1 键彻底没反应了——按下去手感正常,但系统完全不认。
从倒排索引到 BPE:高性能系统为什么总在避免扫描全集
最近在系统学习 Search 和 Information Retrieval 的知识。在看倒排索引(Inverted Index)的时候,我越看越觉得这个结构非常眼熟。直到我想起前段时间写 CS336 作业里 BPE(Byte-Pair Encoding)分词算法的优化逻辑,我才突然意识到:原来这些看似完全不同领域的系统,底层其实都在共享同一种 pattern。
推荐系统的动态算力:当机器跟不上流量,如何让工作负载具备弹性
在 2022 年的年终总结里,我提过当时做的一个“动态算力”项目。那一年,我和另一位同事一起推进了这套系统,陆续接入腾讯新闻、QQ 音乐、全民 K 歌等业务,部分场景节省了约 30% 的成本。
模型压缩之后,为什么推理反而变慢了:一次 CPU Serving 的性能优化实践
·2828 字·6 分钟
之前我负责过一个推荐系统深度学习 Serving 框架的功能开发与性能优化。
我们的系统主要跑在 CPU 上,以 TensorFlow 为主力 inference engine。随着模型迭代,尤其是 Embedding 层越来越大,模型导出、传输和上线变得非常慢,Serving 节点的内存成本也眼看着往上飙。
为什么一个 Python Library 既要锁依赖,又不能锁依赖
起因 # 最近在团队内部重新整理 Python 项目的打包、发布和依赖管理规范,逐渐把各个工程统一收敛到:
1pyproject.toml 2uv 3uv.lock 4wheel 5src layout 6internal package registry 在这个过程中,大家交流最多的往往是一些具体的工具用法:私有源怎么配、build backend 选哪一个、uv 的命令参数怎么写。但我越梳理越发现,这些工程细节很容易盖住一个更基础的问题:
2022
【施工中】gitlab ci docker executor指定用户执行
背景 # 需要在gitlab pipelines中跑一堆测试 其中某些测试需要与rancher交互,在训练集群上执行一个训练任务
gitlab pipelines的默认用户是root,而rancher会默认以当前操作的user进行调度。
浅谈 Cpp Value Categories
·925 字·2 分钟
背景 # 每一个cpp expression都有一个type 和 value category 属性 前者大家都比较了解,但是后者却常常被忽视
[施工中] levelDB 代码阅读笔记 06 iterator
接口 # 一个ABC,后面会继承这个类做各种实现
clean up function # 代码比较好懂,唯一让我感到疑惑的是 clean up function 这部分
levelDB 代码阅读笔记 05 arena
arena是levelDB中的内存池实现
接口 # 没有太多好说的,都非常直观。补了些注释
1 2class Arena { 3 public: 4 Arena(); 5 6 Arena(const Arena&) = delete; 7 Arena& operator=(const Arena&) = delete; 8 9 ~Arena(); 10 11 // Return a pointer to a newly allocated memory block of "bytes" bytes. 12 char* Allocate(size_t bytes); 13 14 // Allocate memory with the normal alignment guarantees provided by malloc. 15 char* AllocateAligned(size_t bytes); 16 17 // Returns an estimate of the total memory usage of data allocated 18 // by the arena. 19 size_t MemoryUsage() const { 20 return memory_usage_.load(std::memory_order_relaxed); 21 } 22 23 private: 24 char* AllocateFallback(size_t bytes); 25 char* AllocateNewBlock(size_t block_bytes); 26 27 // Allocation state 28 // alloc_ptr_ 表示下一个可用的位置 29 char* alloc_ptr_; 30 size_t alloc_bytes_remaining_; 31 32 // Array of new[] allocated memory blocks 33 // 需要注意,vector中每一个元素都是一段内存块(memory, block) 34 std::vector<char*> blocks_; 35 36 // Total memory usage of the arena. 37 // 38 // TODO(costan): This member is accessed via atomics, but the others are 39 // accessed without any locking. Is this OK? 40 std::atomic<size_t> memory_usage_; 41}; 分配策略 # 代码可说的不多,主要想讲讲分配策略
levelDB 代码阅读笔记 04 filter
FilterPolicy接口 # 1 2class LEVELDB_EXPORT FilterPolicy { 3 public: 4 virtual ~FilterPolicy(); 5 6 // Return the name of this policy. Note that if the filter encoding 7 // changes in an incompatible way, the name returned by this method 8 // must be changed. Otherwise, old incompatible filters may be 9 // passed to methods of this type. 10 virtual const char* Name() const = 0; 11 12 // keys[0,n-1] contains a list of keys (potentially with duplicates) 13 // that are ordered according to the user supplied comparator. 14 // Append a filter that summarizes keys[0,n-1] to *dst. 15 // 16 // Warning: do not change the initial contents of *dst. Instead, 17 // append the newly constructed filter to *dst. 18 virtual void CreateFilter(const Slice* keys, int n, 19 std::string* dst) const = 0; 20 21 // "filter" contains the data appended by a preceding call to 22 // CreateFilter() on this class. This method must return true if 23 // the key was in the list of keys passed to CreateFilter(). 24 // This method may return true or false if the key was not on the 25 // list, but it should aim to return false with a high probability. 26 virtual bool KeyMayMatch(const Slice& key, const Slice& filter) const = 0; 27}; 其中CreateFilter的含义是从n个key生成一个 std::string. 生成的std::string可以包含n个key的信息(类似于生成了一个全集) 从而后续判断某个key是否在其中。
LevelDB 源码阅读 03:Cache 与 LRU
从 Cache 接口进入 LevelDB 的 LRUCache、Handle 生命周期与分片并发设计。