2

在字符串性能上,传统 C++库被游戏业打的鼻青脸肿。

 1 year ago
source link: https://www.v2ex.com/t/905072
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

V2EX  ›  C++

在字符串性能上,传统 C++库被游戏业打的鼻青脸肿。

  tool2d · 12 小时 9 分钟前 · 6432 次点击
今年 2022 C++开发者大会上,有一个写游戏的作者,写了个基于 SIMD 优化的字符串,然后对比了传统 std::string 性能,几乎是秒杀了。

要知道 std::string 也进化了那么多年,时至今日,还是被游戏业打的找不到北,只能说游戏业对于性能的无止尽追求的欲望,实在太强了。

作者也开源了( www.youtube.co.jp/watch?v=fglXeSWGVDc ),并附上了性能对比截图:

qevrlYr.jpg
50 条回复    2022-12-28 21:53:02 +08:00
julyclyde

julyclyde      12 小时 6 分钟前

std::string 只是个接口吧,又没规定具体怎么实现
tool2d

tool2d      12 小时 2 分钟前

@julyclyde stl 标准库,怎么可能是接口呢。

你去问任何一个写 C++的,都不推荐你自己改写 stl 的库,因为大概率没官方写的好。

比如 std::string 这种,都是世界顶级科学家写出来的。
julyclyde

julyclyde      11 小时 54 分钟前   ❤️ 2

@tool2d 你好像分不清标准库和标准模板库啊……
建议你还是找任何一个写 C++的多问问,到底是接口还是实现
yehoshua

yehoshua      11 小时 54 分钟前 via Android   ❤️ 1

std::string 毕竟只是标准库,具体应用场景要自己优化的。这是在游戏场景有大规模文字处理下的实现,不至于说传统库就不行了吧。
cubecube

cubecube      11 小时 51 分钟前

如果没有 SIMD 呢?
标准库要兼容各种运行场景不是
tool2d

tool2d      11 小时 49 分钟前

@julyclyde 我知道你的意思,你不就是想说,不同的编译器,有自己特殊的 stl 库实现嘛。

你看我那个截图,跨了 windows 平台,mac 平台, linux 平台。并且对比了 x64 和 arm 架构。

stl 库的设计理念基本都是确定的,性能差距并没你想的那么大。
jmc891205

jmc891205      11 小时 47 分钟前

std::string 的性能拉胯是众人皆知的
julyclyde

julyclyde      11 小时 46 分钟前

@tool2d 不同编译器,各有各的实现方法,虽然也包含你说的 stl ,但其实在这个案例中并不是 stl 而是指标准库
这事跟 stl 就没什么关系吧
tool2d

tool2d      11 小时 44 分钟前

@cubecube "如果没有 SIMD 呢?"

游戏业比较特殊,如果没有 SIMD ,游戏 FPS 就会直接减半,这点很多开发者都没办法接受。

只能强制用户升级 CPU ,加上 AVX 之类的必要属性。
pocarisweat

pocarisweat      11 小时 43 分钟前   ❤️ 4

std::string 首先就应该改名,这玩意只能叫做 std::bytes ,看看人 Rust 和 Swift 这些新语言是怎么处理不定长字符的。

挑战 std::string 的实现非常多,因为字符串在太多领域实在是过于重要了。比如元宇宙公司的 FbString: https://github.com/facebook/folly/blob/main/folly/docs/FBString.md

领域不同,导致对字符串性能的主要需求场景也不同,有些是字符串拼接,有些是快速复制,有些是查找,很难说某个实现真的全部适用。
tool2d

tool2d      11 小时 39 分钟前

@julyclyde 我被你说的有一点晕,你看 std::string 的实现,是模板实现的啊。
missdeer

missdeer      11 小时 38 分钟前   ❤️ 10

OP 的标题作为论点太狭隘了,应该说“在性能上,不用多媒体指令集的 C++库被用多媒体指令集的库打得鼻青脸肿”
paoqi2048

paoqi2048      11 小时 36 分钟前

和 UnrealString 相比较呢?
LaTero

LaTero      11 小时 34 分钟前 via Android   ❤️ 6

“一个写游戏的作者”,说得好像是一个人自己放假没事随便搞的一样,这明明是英伟达一堆雇员画了很长时间专门为图形领域优化的(主要体现在:字符串短,很多时候是从字符串字面量初始化来的,最常用的操作是连接两个字符串)。长字符串这个库和 libstdc++是持平的,而且因为比较 hacky (识别字符串字面量的方法)不可能放进标准库。
Xusually

Xusually      11 小时 34 分钟前

这个 benchmark 图是 32 Byte String 的成绩,std::string 对长字符串的优化本身就稀烂,超短字符串性能还过得去。
litmxs

litmxs      11 小时 27 分钟前 via Android

C++标准库里面的东西本来就拉跨,比如 regex
没性能需求凑合用,有性能需求只能找找专门的第三方库或者自己手搓
像 stl 这种,大部分第三方库或者框架都会自己实现一套,比如 Qt 、UE 、Google 的 Abseil ,Facebook 的 folly 等等
andyhuzhill

andyhuzhill      11 小时 26 分钟前

std::string 性能一直不怎么样啊
大多数的 C++工程都会实现自己的 string 类 不用 stl 的
icyalala

icyalala      11 小时 24 分钟前   ❤️ 20

CppCon 挺好的分享,结果到楼主这里挑出来一个就说什么 "传统 C++库" 被 "游戏页" 打的找不到北,搞个大新闻。。

我贴出来开源地址: https://github.com/RobloxResearch/SIMDString
人家说得很清楚:这是为 3D 程序的使用场景做的优化,其他使用场景性能可能没那么好,甚至比 std::string 更差。
yulon

yulon      11 小时 20 分钟前

但凡你写过几年 C++,标准库的实现从来都是通用而非性能。

你像富文本 GUI 要是直接用 std::string ,内存还不炸了?
lambdaq

lambdaq      11 小时 18 分钟前

路过。。其实这也是为啥 C++ 生态支离破碎的原因。。连字符串这种基础得不能再基础的东西都要发明 n 个轮子争论半天。。所以最后不同的库连最基本的数据结构都不互相兼容。
cxxnullptr

cxxnullptr      11 小时 14 分钟前

OP 能贴一下开源的地址吗,找了半天没找到
glfpes

glfpes      11 小时 13 分钟前   ❤️ 13

建议 OP 去干自媒体,引战拿流量的本领有专业风范。
julyclyde

julyclyde      11 小时 10 分钟前

@tool2d 没有 SIMD 的机器现在还存在吗?
julyclyde

julyclyde      11 小时 9 分钟前

@tool2d std::string 是否由模板实现的那无所谓啊,那只是个实现
STL 是指 vector<T>那类东西啊
CrazyRain0001

CrazyRain0001      11 小时 5 分钟前

c++有性能需求的一般都要自己优化吧。不同 CPU 有不同的接口,SIMD 在某些 arm 上可能还不如编译优化,Inter 的用 IPP 也比 SIMD 直接。最终还要看业务逻辑,这个 stl 没法搞
besto

besto      10 小时 41 分钟前

up 不会觉得 GPU 是 SIMD 吧(手动狗头)
across

across      10 小时 31 分钟前 via iPad

游戏行业大项目一般不用 std ,这个是兼顾各方平衡用的库,性能当然不突出,最多当标杆参考。
游戏里 json 最常见是 rapidjson ,腾讯 milo yip 写的,快十来年了吧,simd 就有用上,3A 大项目很多都用这个库。最近字节也出了一个库,号称比 rapidjson 快来着,还没仔细看过。
encro

encro      10 小时 29 分钟前   ❤️ 1

标准库需要考虑完备性,兼容性,统一性和异常处理等,
你只要砍掉任意需求,节省这方面的性能开支,当然能提升性能。

当我们谈论计算机程序性能时,我们需要同时考虑原因和代价等,这是一个有经验程序员都应该知道的。

发这种文章,不分析原因,
要么作者在盲人摸象、道听途说,
要么就是为了哗众取宠而故意断章取义、混淆是非。
phiysng

phiysng      10 小时 20 分钟前

领域优化的实现比通用实现快很奇怪吗
qieqie

qieqie      10 小时 19 分钟前 via iPhone

你猜为啥他的 benchmark 要比 32B 而不是 24B 以下(gcc/clang sso),或者 32B(neon, sse 宽寄存器),64B(AVX2)以上呢。
Skifary

Skifary      10 小时 17 分钟前   ❤️ 7

多一点包容吧,大多数人应该都有“哇,我发现了一个好厉害的东西,我要去炫耀一下我的发现”的时期,学习和成长都是这么慢慢来的。
qieqie

qieqie      10 小时 5 分钟前 via iPhone   ❤️ 1

首先我没有看这个库源代码和视频,根据常识盲给几个结论:
对于小于 24 字节的 string ,编译器在 gcc5/clang6 之后的实现都会有明显性能提升,但是这个 simd string 不会甚至略降(simd 要做 align 和 padding )。
对于大于 32 字节的 string ,simd string 在不支持 avx2 寄存器的环境下都会成倍降低或者 fallback 。
nulIptr

nulIptr      9 小时 41 分钟前

笑死,你能说下哪个正经项目用的 std::string 吗
bashbot

bashbot      9 小时 12 分钟前   ❤️ 1

@nulIptr #33

我司做命令行工具的,EDA 行业软件,就是用 std::string ,不然用 char*吗。
能用 STL/std 就不用其他,这个是我们开发的惯例。使用第三方库和代码涉及兼容性、后期维护、授权问题,严重影响开发效率。至于什么字符串性能,加机器就能解决的问题,根本不用考虑。
想想要兼容十年前的服务器硬件和 Arm 最新的硬件,要兼容 Centos6 和 RHEL6~8 ,选一个第三方库前期调研得投入多少精力。老板们常说的话是:代码重构?没有 10 倍以上性能提升就不要考虑重构。

所以什么谁打败谁,完全是看需求,符合使用场景的就是好的,不好的话就是用的人没用好。
dabaibai

dabaibai      8 小时 41 分钟前

15 年前做游戏 都是自己写 string 写字符串渲染 ,字符编码转换等

15 年后的今天 这些东西都进引擎了 也没必要纠结了 用就完了
msg7086

msg7086      8 小时 30 分钟前 via Android

做游戏可以强迫用户换 CPU ,做标准库也可以强迫用户换 CPU 吗?不如换用 avx512 ,人人都得用志强或者 zen4 ,速度快还能拉动 GDP 。
pi1ot

pi1ot      8 小时 20 分钟前

这一行里不会有人拿 std::string 做性能对手,就像做浏览器的没人拿 IE 比性能一样。
openmm

openmm      7 小时 25 分钟前

吓死了,光看标题还以为出大事,c++又被吊打了
tyzandhr

tyzandhr      7 小时 24 分钟前 via Android

所以写 c++的诸位都用的是什么字符串库?莫非用的是 char 数组?
tool2d

tool2d      7 小时 12 分钟前

@tyzandhr 用自己写的短字符优化的库,理论上 std::string 算法没问题,有问题的是默认的内存分配器,实在很不给力。
tool2d

tool2d      6 小时 59 分钟前

@icyalala "人家说得很清楚:这是为 3D 程序的使用场景做的优化,其他使用场景性能可能没那么好,甚至比 std::string 更差。"

这仅仅是你的看法,我个人看法和你刚好相反,32 字节优化后的字符串库,对于覆盖 90%的应用场景都够了。剩下 10%就用作者视频里提到的 readonly 字符串。

无脑用 std::string ,会导致内存碎片过多,实在很不推荐。
icyalala

icyalala      6 小时 55 分钟前   ❤️ 4

@tool2d 这不是我的个人看法,这是你的分享里原作者的看法,原话就是这样
Limitations:...
SIMDString is designed and benchmarked for the usage patterns found in games and other real-time 3D applications. It may perform less well and even underperform std::string for applications with different usage patterns.
hazardous

hazardous      6 小时 54 分钟前

这就是 C++的优势啊,追求极致的性能,有特殊优化的需求那就自己去实现。其它语言不这么干的那就是对性能要求不够高。
tyzandhr

tyzandhr      4 小时 49 分钟前 via Android

@tool2d 你是说 glibc ?
jmc891205

jmc891205      4 小时 44 分钟前

@bashbot EDA tool 不需要大量处理字符串,std::string 不会成为性能瓶颈
superares

superares      3 小时 36 分钟前

要不试试用 AVX512 ?估计更快
dazhangpan

dazhangpan      3 小时 35 分钟前

对于任何一名做底层软件的资深开发者来说,游戏业这点优化,小儿科啦
nightwitch

nightwitch      3 小时 29 分钟前 via Android

只比时间不比空间吗。做 simd 肯定需要 padding 到字节对齐的
nmap

nmap      1 小时 54 分钟前

std::string 性能不行是众所周知吧
LuckyPocketWatch

LuckyPocketWatch      1 分钟前

首先,std::string 是一个标准。不同的编译器的 std::string 也是不一样的

其次,std::string 性能不行我从来不认可的,一个字符处理能够兼顾通用性和性能,各版本的 std::string 已经做到非常好,至少,vs 和 gcc 的都是如此

最后也是最重要的,说 xxx 的效率碾压 std::string,这里没有说清楚一个很重要的问题是,你在测试前加了多少定语?如果定语足够多,我也可以写出一款碾压 std::string 的字符串处理函数

附:你说开源,不贴个 github 或 gitlab 的地址么,实在不行 gitee 也行,你贴个油管地址我不是很认可。。

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK