主页

硬件与编程语言的内存模型

之前对于C++的原子变量操作总是感到困惑,在读到关于Go 1.19更新内存模型背景的系列文章后有了一些新领悟。本文将从硬件出发进行介绍,然后看看一些「现代」编程语言规范中定义的内存模型,最后简单聊聊Go 1.19内存模型的更新。

阅读更多

JPEG编码原理与快速编解码

NVIDIA在2018年6月发布了基于GPU加速的用于解码JPEG的nvJPEG,而实际上早在1998年,libjpeg/SIMD就开始使用SIMD指令集对JPEG编解码进行加速。为什么JPEG编解码过程可以被SIMD或GPU加速?为什么我们又尚未看见类似的对PNG进行加速的项目?本文将从JPEG编解码原理出发,简单讲解SIMD加速的原理,并简要说明PNG不能被加速的原因。

阅读更多

扔球进桶与负载均衡

同事介绍负载均衡算法时透露,其原B站leader透露说B站的负载均衡算法是基于一篇对扔球进桶问题讨论的论文。正好笔者曾看过相关内容,也深感这一简单的概率游戏有着让人意外的结果,故希望写一系列的文章,介绍这一简单而优美的结果。(本文首发于腾讯云+社区。)

阅读更多

深入Go:垃圾回收的演进

Stop the world 是讨论垃圾回收(Garbage Collection,GC)时绕不开的话题,曾经Go语言的GC机制也威胁着服务的响应时间——Discord技术团队的文章Why Discord is switching from Go to Rust讨论了Go语言GC带来的问题。Go通过版本迭代已经极大地改善了GC的问题,平均每次STW时间从100+ms降低到了0.5ms——是什么神奇的魔法使得世界几乎无需暂停?在本文中,我们通过提问、解答的方式尝试对该演进的主要过程进行梳理。(本文首发于腾讯云+社区。)

阅读更多

深入Go:Context

在理解了 package context 的使用后,我们很自然地想问其背后的设计哲学有什么?实际上,我们发现无论是在关于 Context 的批评/讨论也不少,那么 Context 的设计合不合理?带着这些疑虑,我们深入 context 的源码,尝试对这些问题作出解答。

阅读更多

深入Go:使用context包轻松完成并发控制

一次请求到达后台,需要并发启动大量的任务以组合出最终的响应,如何设计实现:一个请求到来之后,X秒超时;超时或遇到错误时立即返回,并取消所有并发任务?其实用了Go context包,这个问题就可以非常优雅自然地解决,并且了解Context之后你会赞叹:“哇,真就该这么设计!”

阅读更多

深入Go:错误的包装与解包

仔细想想,我们的Go代码中可能有四分之一的代码都是和错误处理相关的,而我们已经接受了,error无处不在。但似乎Go的error处理并不够强大,也缺乏统一的错误处理流程的逻辑;在经历了大量的讨论后,Go 1.13引入了错误的包装和解包,也许某种程度上可以优化我们的错误处理流程。

阅读更多

深入Go:并发迷思-消失的赋值语句

对全局变量的赋值,为何无缘无故消失?等候了千万个时钟周期的打印语句,为何发现变量没有一丝改变?意料之外的结果,却为何又是在情理之中?这究竟是编译器的背叛,还是随机的巧合——本篇文章将带您深入Go内存模型,一起走近并发。

阅读更多

深入Go:sync.Map

我们在使用Go的项目中需要有并发读写的map时,我们了解到Go提供sync.Map这一数据结构;通过对其简单了解,发现它正好适合我们需要的场景。随着了解的深入,我们又有了疑惑:为什么不像Java SE 8之前的ConcurrentHashMap一样,使用分段锁?为什么在内部需要一个哨兵指针expunged?这两个问题我们简单Google后都没有找到解析和讨论,因此我们决定深入sync.Map的源代码,尝试回答这两个问题。

阅读更多