Coroutine

从一般概念上说, 协程是特殊的函数调用: 被调用的函数可以在可控的位置被中断,然后在下一次调用时,继续从上次中断的位置继续执行。

本文主要通过Python的协程来介绍协程, 这是我唯一熟悉的一种协程实现.

Classic Coroutine

下面的python代码很好的说明了协程的核心功能

def co_routine():
    recv0 = yield 996  # hangs here after first coro.send
    
Read More

GDB with Python

这篇文章的主要应用场景是调试Python的C/C++ Extension

  1. 同时使用pdb / gdb 进行调试. 通俗点说, 既可以break在 .py 文件中,也可以break在 .cc 文件中
  2. 在gdb中不但可以获得常规的调试信息, 还可以获得python VM 的调试信息, 例如获得python的调用栈, 访问Python局部变量等. 这将会在调试exception时(如Segmentfalut)非常有用, 这种场景下,
Read More

Bazel Notes

这是一篇2019年左右的记录, 内容可能过时, 也不太全面

杂谈

Bazel是Google为Monorepo服务而开发的构建工具.

首先是巨大,当问题的规模变大,事情总是会变得更复杂. 而Google面对的"巨大Monorepo",应该是世间罕有的.

然后是Monorepo,这极大的影响了代码的组织风格.例如,你要写一个操作系统内核ProjectOS,还要写一个游戏ProjectGame.在传统的开发习惯中,这两个项目会组织到两个不同的Repo里,PorjectOS和ProjectGame之间无法直接相互引用,例如,你在ProjectOS里写了一个高级的数据结构,想要在Game里也使用,要么直接复制粘贴,要么是创建一个新的CommonRepo,把可公用的代码都放在Common里,然后两个项目各自引入Common作为依赖.

使用MonoRepo则不存在这个问题,Game可以直接依赖OS内的组件,按照Bazel的语法描述,就是在Game中可以直接使用@ProjectOS//path/to/package:AdvancedStruct.当然,你仍然可以选择重构一个Common出来,但是现在已经没有这种必要了.

从技术层面说,在使用"巨大Monorepo"时,Bazel相对现有编译系统的优势能充分展现.你的项目离"巨大Monorepo"越远,使用Bazel的优势就越不明显. 宽泛的来说,对于大部分项目,使用Bazel都不能带来明显的技术收益.

一般而言,使用Bazel的优势是并不是体现在技术层面.而是让你的代码能无痛使用谷歌的开源组件. 原因很简单, Google的项目都是基于Bazel的,如果你不用Bazel,就需要自己做一些额外的工作.

换个角度来看,这也是谷歌的"阴谋":如果Google外的开发者不用Bazel,那么当Google需要依赖外部项目时,就需要手动把这些项目转换成Bazel的;而如果全世界的程序都用Bazel来组织编译,那么Google就可以无缝的从开源世界汲取力量.

吹Bazel的帖子到处都有,所以这里只说黑点,如果这些黑点你并不很care,那么使用Bazel应该是个不错的选择

  1. Bazel是后来者,熟悉它的开发者比较少,加上学习成本高,可能需要有若干"Bazel"专家负责整个构建系统的维护.
  2. 对于已经成熟的大中型项目,迁移到Bazel的时间/人力成本会比较高,而这一般也不会带来明显的收益.最好在项目早期使用Bazel
Read More

Unix related things

这是一篇2017年左右的记录, 仅用作分享

  • 在shell内能干的事,我们都可以比较简单地通过系统调用实现.
  • `称为反引号,^称为脱字符,常用来表示CTRL
  • windows的系统调用是不开放的,windows下只能直接使用windows.h里的windows API.
  • /dev目录下的设备是供用于程序直接使用的,主要由block,char,pipe,socket类型
    • 并不是所有设备都能映射为这种形式
  • /sys/device/目录称为sysfs,他下面存放了所有设备的信息.(不能直接从/dev获得任何设备信息)
    • udevadm info
Read More

Docker

这是一篇2017年左右的记录, 内容可能已经过时

  • Docker的image类似于Git的repo,而docker的tag则类似于git的branch
  • 由于内核共享, Docker container 里的uid/gid是和宿主机复用的, 所以相关的鉴权系统也和系统一致.
    • 用户名可能不一致, container内可以使用自己的用户名.
    • 可以使用 --user来指定docker container内所有进程的执行身份
  • Docker 可以近似为特化的虚拟机,除了Kernel外,所有的其余部分都可以是Docker独占的。
    • 例如,可以制作完整的OS镜像,这些OS镜像除了没有内核,其余都和正常的OS是一致的。
    • Docker之间的隔离相比VM要浅一些,可能存在一些安全问题;另一方面,VM则由于可攻击面更大,也有安全问题
  • Docker可以说是一个Utility, 并没有自创新技术,所以Docker中的技术主体为
Read More

Bitcoin and Blockchain

这是一篇越在2016年左右记录的笔记, 仅仅分享

比特币

比特币作为区块链的元祖, 引入了许多基本概念, 能作为学习区块链的开端.

目的

比特币的意图是实现一个去中心化的货币系统, 比特币的发行和支付由参与网络的所有节点所控制.

从原理上说, 所有节点都完全独立, 也就是说: 每个节点都拥有完整的货币数据,包括发行记录及支付记录; 每个节点都可以发行货币,也可以发起支付.

比特币主要解决了这个问题: 如何让网络中的所有节点都可以"彼此不信任"的"达成共识" . 彼此不信任是指:对于任意节点X而言, 其他节点彼此相同,没有特殊的"可信"节点(或者说,你无法判断某个节点是否可靠). "达成共识"是指, … Read More

Shared Library

正确而高效的使用动态库是一个很复杂的话题,这需要开发者编译和链接有相当深入的理解.

Read More

The Building Blocks of Transformers

Transformer完全改变了2017年后NLP领域的模型方向, 从某种意义上说,Bert,GPT等模型都是Transformer模型的变体, 虽然模型结构有各种改变, 但是其中的一些基本计算单元则变化较小.

Transformer几乎就是为了改善计算性能而专门设计的模型.

  1. 完全没有RNN之类的循环计算需求, 这就极大降低了计算过程中的顺序依赖, 可以极大提高并行性.
  2. 大量使用矩阵乘, 不使用卷积这种计算强度不够大的算子

正是由于Transformer使用到的基本计算单元非常简单, 几乎就只有 gemm, +-*/, layernorm, softmax, 也没有奇怪的计算流程, 所以原文的作者将其称为一个"简单"的模型是很有道理的.

本文就是简单记录Transfomer中使用到的基本计算单元.

Basics

Read More

A note for cmake

A Note for CMake

CMake可以说是目前C++项目的标准构建系统, 尽管它有很多不足, 但是它已经成功的替换掉了autoconf这一代的构建工具. 除非有足够的理由, 在选择构建系统时, CMake总是应当第一优先考虑.

我熟悉的构建系统只有CMake和Bazel, 事实上, 如果能满足若干客观条件的话, 我更愿意使用Bazel, 不过这篇主要记录的是CMake, 所以还是以CMake为主. 在我看来, CMake主要的优缺点如下:

Pros:

  1. Imperative:
Read More