V2EX lxdlam 的所有回复 第 1 页 / 共 7 页
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX    lxdlam    全部回复第 1 页 / 共 7 页
回复总数  138
1  2  3  4  5  6  7  
这个事儿最重要的大背景是日本在去年颁布的《信用卡安全指南 6.0 版》[1],里面强制要求了所有日本在线商户必须在最迟 2025 年 3 月底强制启用 3DS 验证,这一年日本本地银行跟支付供应商都在鸡飞狗跳,而根据大家都明白的日本 IT 基建水平,不少支付方式供应商选择一刀切,停止所有境外支付方式支持,就造成了现在的局面。这件事不止影响了任天堂,苹果之前中断新的境外信用卡也是有这个背景的。

1. https://www.meti.go.jp/press/2024/03/20250305002/20250305002.html
非常棒的游记!
这个问题非常得“巧妙”,因为他混合了三个东西,把这个结果拖向了一个“记住就行”的深渊。

1. 返回值的处理:根据 Go 关于 [Return Value]( https://go.dev/ref/spec#Return_statements) 的规范,当你声明一个返回值的时候,你实际上是声明了一个临时对象,区别仅存在于这个返回对象是有名字还是没有名字的;
2. Defer 的作用时机:根据 Go 关于 [Defer Statement]( https://go.dev/ref/spec#Defer_statements) 的规范,`defer` 的作用时机在 `return` 的所有 Value 都被计算且赋值完毕后,真实返回前执行;
3. Go 对闭包的处理:根据 Go 关于 [Function literals]( https://go.dev/ref/spec#Function_literals) 的规范,闭包内捕获的自由变量会被共享;换句话说,你可以理解为闭包实际上捕获了外部变量的指针,对其的修改会同步到原始对象。

花点时间理解上面三个规范会带来的代码作用。

现在我们来分析代码:
- 在 Case1 中,由于返回值被具名了,`return t` 实际上可以理解为 `t = t; return`,也就是仅仅重新赋值,之后执行的 `defer` 重新修改了 `t`,导致返回的值产生了变动。
- 在 Case2 中,由于返回值匿名,假定返回值是一个隐藏变量 `tForReturn`,`return t` 实际上可以理解为 `tForReturn = t; return`,此时虽然你的 `defer` 修改了 `t`,但是由于返回的对象是 `tForReturn`,获取的返回值并没有发生变化,一切正常。当然,此时你再次在 `foo` 调用后查看 `t` 的值,它确实也会是 `4`,`defer` 的作用生效了。

P.S. Go 的规范对这种行为没有明确的规定,上面的三个 spec 其实也只能说是“模糊”描述了作用原理,还是要观察编译器的实现实锤,这也是这门语言天天开天窗擦屁股的核心包袱之一;具名返回值这个特性本身也有很强的“拍脑袋”属性,它确实有用,但是没有有用到这个程度,结果反而引入了更多的混淆。
@lxdlam #68 第二段漏了:通常认为的所谓 -> 通常认为的所谓 Coroutine 更快,建立在那些需要频繁 context switch 的任务上,比如最经典的就是 I/O polling 。
所有的 Coroutine ,无论有栈无栈还是夹在中间的什么混合模式,这个代码总是要被执行的。谁来执行呢?我援引 Solaris 最经典的 LWP 设计:

https://i.imgur.com/jLDht8i.png

本质来说,从一个纯粹的 User program 或者被语言包裹好的这个"乌托邦"来看,OS Thread 就是新的 CPU Cores ,我们不妨叫他 Coroutine Process Unit ,其他的概念几乎等效,无非就是在这个新的 CPU Cores 上看这个新的调度器在做什么操作罢了;只不过我们有一个得天独厚的优势,就是这一切都发生在 User Space ,所有的 context switch 之类的操作都有很大空间不会切换到 Kernel Space ,也不需要跟特定 OS 信息交互,这样就能节省一大部分开销。通常认为的所谓

但是这能说明谁比谁更快吗?尝试用你的 workload 回答我下面三个问题:
1. 这个程序对 CPU 的 locality 要求有多高?无论是基于 NUMA 的同 Node 访问或者 Cache line 的访问优化,你需要它表现到什么样子?
2. 这个程序对 IO 的定制需求如何?一个 epoll/kqueue 就足够,还是需要 DMA/RDMA 这种需要外部 driver 交互的 IO 支持? Runtime 跟你的通信调度如何处理?
3. 这个程序的计算密集程度如何?是可以切成无互访的无状态并发,直接分发完数据 CPU 猛算,还是有高频的互访,实际上存在特定的通信效率瓶颈?

这三个问题只是一个例子,如何去考虑线程跟 Coroutine 的开销。大部分 Coroutine 退化到最后就是一堆普通的线程,插入了一些语言 Runtime 带来的额外钩子,这些钩子的成本显然随着 Coroutine 的增加会有所上升。

但是这个边际成本出现剧增的点在哪儿?不同 Workload 的答案不一样,拍脑袋得不出答案。不要想当然认为线程跟 coroutine 谁更好谁更快,做工程的要拿 benchmark 说话,而不是讨论假大空的概念。如果真对这个问题感兴趣,可以在一些 HPC 任务上跑跑 poc ,看看 HPC 工程师调 CPU Affinity 和 openmp 的观察和优化逻辑。
@w568w #9 如果你*每次*都使用 `launch(newSingleThreadContext()){}` 的话,它确实能被*认为*是一种线程的调度集合。但这只是 Kotlin 给出了底层调度的用户调优空间,Kotlin 的协程仍然是基于状态机的调度。
async/await 真正的含义并不是“显式切换上下文”,如此说来为何 goroutine 也需要 "go func()" 才能启动并发调度?这难道不是一种类似于 "yield something" 的显式切换上下文吗?

从 Delimited Continuation 的角度说,async/await 是 F#/C# 发明出来用来模仿 Delimited Continuation 的 shift/reset, prompt/control 算子的,这一定程度上解释了函数染色问题从何而来:我们需要显式标记哪些部分能够被编译期改写,这样才能准确地把 k : Continuation 传到这些部分。与之相对的是 Scheme 的 continuation ,任何 continuation 都是无界的,也就是说会捕获到整个 runtime ,这对一个**后续接入** continuation 的语言实现有巨大的 breaking change (在 chez 中执行 `(call/cc (lambda (cc) (cc cc)))`,你会得到 `#<system continuation in new-cafe>`)。

而这样说有一些吊书袋,我们不妨简单思考一下所谓的 coroutine 是怎么编译的?

当我们遇到一个类似于如下的代码

```
let coro = async { time.sleep(5000) }

// some busywork

await coro
```
时,我们单纯从语法考虑,我们如何将 coro 正确编译成我们想要的结构呢?我们自然能想到很多种做法,至少我们可以为 coro 创建一个简单的 reference object ,去轮询来看它是否完成,并把 await 自动重写成 while not coro.ref.isFinished() {} 的一个 busyloop 就可以了(对于有栈来说可以是用户态的 uthread.join(),对于无栈来说可以是 state in [Done, Exception])。

所以,本质来说,async/await 是定界,界定了到底哪些代码需要被识别成一个 remote track 的对象,并正确插入调度代码。

这个的后续遗留了更多好玩的问题,感兴趣的朋友可以从这些起点思考:
1. 根据前文描述,"go func()" 某种程度也是定界,那跟 async/await 的核心区别是什么?这将为你导向有栈和无栈最核心的区别,究竟“栈”如何让 goroutine 不需要考虑函数染色问题?
2. 如何实现一个可用级别的编译器,编译我们的协程?他们的底层模型其实很相似,但是要搞懂无栈协程的编译难度比较大,你可能需要真的理解 continuation 和 cps conversion 才能明白看似简单的东西背后有多少篇 paper 和大佬支撑。
256 天前
回复了 lxdlam 创建的主题 职场话题 关于捐赠“抵扣”个税的经济账
@ltyj2003 是的,这个应该是主要动机。
在 GF(2) 域上解线性方程组。
是索尼的问题,我是 Xperia 1 V ,偶发会掉,有的时候能一直是 L1 ,有的时候自己莫名其妙就掉 L3 了。最麻烦的地方在于每次都只有在比如开 Netflix 看剧的时候,看分辨率迟迟上不去才会发现,然后打开 DRM check 实锤了再重启,不胜其烦。
先问是不是再问为什么。

FP 跟 “OOP” 本来就是正交的概念,与 FP 相对的是 Imperitive Programming ,而 FP 可以看作一种 Declartive Programming 。在 1994 年确定的 ANSI Common Lisp 标准中,Common Lisp Object System ( CLOS )已经被完整定义,这是一个完整的对象系统,而被广泛实现的 Meta Object Protocol ,更是后面 Java AOP 的真正前驱。同样,1996 年 OCaml 继承 Caml 衣钵,在 StandardML 基础上发展出了完整的 Object 系统,这也是一个完整的 OOP 系统。而 Scala 跟 Clonjure 这种本身就诞生于 JVM 的语言,更是天生就具有 OOP 能力。
@SimonOne uv 是替代 pip 的,rye 是 flask 作者 mitsuhiko 创始的,他觉得 Python 的研发生态链比起 rust 实在是太烂了,自己搞了一个工具关注整个研发生命周期,使用 独立 python 解释器 + venv + pip + pyproject.toml 等既有生态来管理。后面 astral 团队开发完 uv 之后跟 mitsuhiko 沟通,接管了 rye 项目( https://astral.sh/blog/uv )。

从关系上来说,rye 是一个研发管理工具,基于 project 粒度隔离 python 解释器、venv ,自然也就隔离了包管理生态,uv 跟 pip 在 rye 里可以互换,ruff 也不是强制要求接入。

从我个人体感来说,rye + uv + ruff 就是目前最舒服的方案,我有用来实验的 jupyter 项目,也有打包成 oci 的纯 python 项目,rye 都能非常完美去接入和使用(除了某些模型代码里面写死了 pip 之外)。

P.S.,关于 Python 开发者体验和 rye 本身,mitsuhiko 在 rye 创始之初就有个 discussion ,值得一读: https://github.com/astral-sh/rye/discussions/6
@lxdlam 记忆有偏差,最近一年应该
1  2  3  4  5  6  7  
关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5228 人在线   最高记录 6679       Select Language
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.5 36ms UTC 05:56 PVG 13:56 LAX 22:56 JFK 01:56
Do have faith in what you're doing.
ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86