Changkun's Blog欧长坤的博客

Science and art, life in between.科学与艺术,生活在其间。

  • Home首页
  • Ideas想法
  • Posts文章
  • Tags标签
  • Bio关于
Changkun Ou

Changkun Ou

Human-AI interaction researcher, engineer, and writer.人机交互研究者、工程师、写作者。

Bridging HCI, AI, and systems programming. Building intelligent human-in-the-loop optimization systems. Informed by psychology, sociology, cognitive science, and philosophy.连接人机交互、AI 与系统编程。构建智能的人在环优化系统。融合心理学、社会学、认知科学与哲学。

Science and art, life in between.科学与艺术,生活在其间。

282 Blogs博客
171 Tags标签
Changkun's Blog欧长坤的博客
idea想法 2020-10-30 00:00:00

Getting Goroutine ID获取 Goroutine ID

Possibly the fastest implementation for getting a goroutine ID across all Go versions with Go 1 compatibility guarantee.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
// Get returns the ID of current goroutine.
//
// This implementation based on the facts that
// runtime.Stack gives information like:
//
//   goroutine 18446744073709551615 [running]:
//   github.com/changkun/goid.Get...
//
// This format stands for more than 10 years.
// Since commit 4dfd7fdde5957e4f3ba1a0285333f7c807c28f03,
// a goroutine id ends with a white space.
//
// Go 1 compatability promise garantees all
// versions of Go can use this function.
func Get() (id uint64) {
	var buf [30]byte
	runtime.Stack(buf[:], false)
	for i := 10; buf[i] != ' '; i++ {
		id = id*10 + uint64(buf[i]&15)
	}
	return id
}

可能是具有 Go 1 兼容性保障的全版本获取 gorountine ID 的最快的实现

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
// Get returns the ID of current goroutine.
//
// This implementation based on the facts that
// runtime.Stack gives information like:
//
//   goroutine 18446744073709551615 [running]:
//   github.com/changkun/goid.Get...
//
// This format stands for more than 10 years.
// Since commit 4dfd7fdde5957e4f3ba1a0285333f7c807c28f03,
// a goroutine id ends with a white space.
//
// Go 1 compatability promise garantees all
// versions of Go can use this function.
func Get() (id uint64) {
	var buf [30]byte
	runtime.Stack(buf[:], false)
	for i := 10; buf[i] != ' '; i++ {
		id = id*10 + uint64(buf[i]&15)
	}
	return id
}
idea想法 2020-10-19 00:00:00

Benchmark Testing: The Extras基准测试的番外

Many people have written benchmark tests. In Go Nightly Reading Episode 83, Reliable Performance Testing for Go Programs, we shared how to use tools like benchstat and perflock for rigorous and reliable performance testing. That session briefly discussed the measurement methodology and implementation principles of benchmarks, but due to time constraints, the coverage wasn’t deep enough. So today, let’s further share two details that weren’t covered in Episode 83, but are easily overlooked in certain strict testing scenarios:

  1. When running benchmarks, the code under test is executed more times than b.N. As discussed previously, the testing package runs the code multiple times, gradually predicting how many times the code can be executed consecutively within the required time range (e.g., 1 second, resulting in, say, 100,000 iterations). But there’s an implementation detail: why doesn’t it incrementally accumulate execution times across multiple runs such that t1+t2+…+tn ≈ 1s, and instead searches for the maximum b.N where the total loop time ≈ 1s? The reason is that incremental runs introduce more systematic measurement error. Benchmarks are typically unstable in early iterations (e.g., cache misses), and accumulating results from multiple incremental runs would further amplify this error. In contrast, finding the maximum b.N where the total consecutive execution time satisfies the required range amortizes (rather than accumulates) this systematic error across each test.
  2. Does this mean the testing package’s implementation is perfect, and all we need to do as users is write benchmarks, run under perflock, and use benchstat to eliminate statistical errors? Things aren’t that simple, because the testing package’s measurement program itself also has systematic error, which in extreme scenarios can introduce significant bias. Explaining this requires more space, so here’s an additional article for further reading: Eliminating A Source of Measurement Errors in Benchmarks. In this article, you can learn more about what this intrinsic systematic measurement error is, and several reliable approaches to eliminate it when you need to benchmark such scenarios.

很多人都编写过 Benchmark 测试程序,在 Go 夜读第 83 期 对 Go 程序进行可靠的性能测试 (https://talkgo.org/t/topic/102) 分享中也跟大家分享过如何利用 benchstat, perflock 等工具进行严谨可靠的性能测试。在那个分享中也曾简单的讨论过基准测试程序的测量方法及其实现原理,但由于内容较多时间有限对性能基准测试的原理还不够深入。因此,今天跟大家进一步分享两个未在第 83 期覆盖,但在进行某些严格测试时较容易被忽略的细节问题:

  1. 进行基准测试时,被测量的代码片段会的执行次数通常大于 b.N 次。在此前的分享中我们谈到,testing 包会通过多次运行被测代码片段,逐步预测在要求的时间范围内(例如 1 秒)能够连续执行被测代码的次数(例如 100000 次)。但这里有一个实现上的细节问题: 为什么不是逐步多次的累积执行被测代码的执行时间,使得t1+t2+…+tn ≈ 1s,而是通过多次运行被测代码寻找最大的 b.N 使得 b.N 次循环的总时间 ≈ 1s?原因是逐步运行基准测试会产生更多的测量系统误差。基准测试在执行的初期通常很不稳定(例如,cache miss),将多个增量运行的结果进行累积会进一步放大这种误差。相反,通过寻找最大的 b.N 使得循环的总时间尽可能的满足要求范围的连续执行能够很好的在每个测试上均摊(而非累积)这一系统误差。
  2. 那么是不是可以说 testing 包中的实现方式就非常完美,作为用户的我们只需写出基准测试、在 perflock 下运行、使用 benchstat 消除统计误差后我们不需要做任何额外的操心了呢?事情也并没有这么简单,因为 testing 包的测量程序本身也存在系统误差,在极端场景下这种误差会对测量程序的结果产生相当大的偏差。但要讲清楚这个问题就需要更多额外的篇幅了,所以这里再额外分享了一篇文章 Eliminating A Source of Measurement Errors in Benchmarks(https://github.com/golang-design/research/blob/master/bench-time.md),以供你进一步阅读。在这篇文章里你可以进一步了解这种测量程序内在的系统测量误差是什么,以及当你需要对这种场景进行基准测试时,几种消除这类误差源的可靠应对方案。
idea想法 2020-10-01 00:00:00

Hello你好

Hello world!

你好世界!

Eliminating A Source of Measurement Errors in Benchmarks消除基准测试中的测量误差根源

Published at发布于:: 2020-09-30   |   Reading阅读:: 14 min

About six months ago, I did a presentation that talks about how to conduct reliable benchmarking in Go. Recently, I submitted an issue #41641 to the Go project, which is also a subtle problem that you might need to address in some cases. The issue is all about the following code snippet: 1 2 3 4 5 6 …

大约六个月前,我做了一个关于如何在 Go 中进行可靠基准测试的演讲。 最近,我向 Go 项目提交了一个 issue #41641, 它涉及一个在某些情况下需要处理的隐蔽问题。 问题的核心在于以下代码片段: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 func BenchmarkAtomic(b *testing.B) { var v int32 …

Read More阅读更多 »

Setup Wordpress in 10 Minutes

Published at发布于:: 2020-03-29   |   Reading阅读:: 3 min
Last week, my colleague asked me to set up a Wordpress server, and I remember how painful to setup it many years ago. It requires MySQL and PHP. Therefore, it may introduce many security leaks. My website at the moment still can receive Wordpress attack. Today, I discovered a rapid solution to set up a Wordpress server using Docker, and it also solves the problem with Let’s Encrypt. Let’s check it out.
Read More阅读更多 »

我为什么不再写博客了?

Published at发布于:: 2020-03-08   |   Reading阅读:: 1 min

这篇文章也是一篇博客文章,读者可能会质疑:这不是与这篇博客的主题相矛盾吗? 我目前觉得还没有,但可以预见的是,这个博客在未来的一年以内不会更新任何内容。 我的博客的更新频率越来越低,我为什么不再写博客了呢?或者严谨的说,我为什么不再进行频繁的博客写作了呢?

Read More阅读更多 »

2019 年终总结

Published at发布于:: 2020-02-01   |   Reading阅读:: 2 min

当周围的同龄人都已工作的工作、回国的回国、结婚的结婚以及生子的生子, 迈入人生的下一个重要的阶段时,当回顾我的 2019 时,似乎我已经从早年那个目标明确、 总是走在他人前面的那个 “佼佼者”,逐渐沦为了一个不知前路在何方、似乎已经落人一步的 “平庸” 之人。相比往年,我的 2019 似乎过的格外的 “精彩” 却又异常的 “茫然”。

Read More阅读更多 »

2018-2019 读书清单

Published at发布于:: 2020-01-22   |   Reading阅读:: 2 min

2018 年没有更新书单,原因有很多。现在与 2019 年一并放出,这两年在做毕业论文和做科研两方面影响下,这两年读的书都偏技术和理论,读得更多的反而是论文(论文清单我们以后有机会再表)。人文类的闲书的数量也大大减少,所以整体读书的时间也大大延长,2018 年几乎没读完几本书,这也是当时没有更新书单的主要原因之一。

这个清单里还有好几本读过的与自己博士研究方向相关的书籍没有列出,也算是延续了以前读书清单的传统:专业相关的书籍不在此列表中。

Read More阅读更多 »

Ten years of blogging

Published at发布于:: 2019-06-16   |   Reading阅读:: 1 min
写博客似乎已经十年了,这十年间我没有对博客进行过任何有目的性的宣传, 纯粹的 “Just for fun”。而两天前,我收到了迄今为止最大的一笔匿名赞助。 特别致谢。

Rethinking the Reflections on Communications and Trusts

Published at发布于:: 2019-05-15   |   Reading阅读:: 1 min

沟通和信任原本是人与人之间打交道的两个基本因素,但这两个因素在跨文化的背景下显得越来越不经如人意。 从今年三月份开始,我步入了我的博士生涯,在这随后的两个月里我开始重新思考沟通与信任这两个主题。

Read More阅读更多 »
6 7 8 9 10 11 12 13 14
© 2008 - 2026 Changkun Ou. All rights reserved.保留所有权利。 | PV/UV: /
0%