Remaking Celeste's Lighting (2017)10 months agohttps://noelberry.ca/posts/celeste_lighting/《Celeste》的灯光设计旨在增强游戏情绪与氛围,使登山探索过程更具沉浸感初始灯光方案采用复杂的网格系统实现,虽然速度快但存在边缘情况bug开发了新的'剪裁实现法'——通过纹理处理光影效果,简化流程但增加了纹理交换次数采用单通道遮罩进行优化,通过不同色彩通道实现在单张纹理上存储最多4种光源最终利用游戏低分辨率特性,将所有光源整合到一张大纹理中,显著提升了运行性能
A compact bitset implementation used in Ocarina of Time save files10 months agohttps://github.com/jb55/oot_bitset灵感来自《塞尔达传说:时之笛》的极简零开销旗帜系统采用C/C++和Rust实现,实现高效旗帜存储在存档文件中存储数百或数千个单比特旗帜,不浪费字节使用uint16_t数组实现空间高效存储(1个字=16面旗帜)C语言版本仅需头文件,Rust版本依赖极小;无需堆分配通过无分支位操作实现零成本抽象,性能优异可扩展性从1到4096个字(65,536面旗帜)直观的索引方式便于调试(例如0x12对应字1位2)包含设置、清除和检查旗帜的功能函数兼容C99及以上版本编译器,并通过Cargo支持Rust
Understand CPU Branch Instructions Better10 months agohttps://chrisfeilbach.com/2025/07/05/understand-cpu-branch-instructions-better/分支指令对于CPU程序中的决策制定至关重要。顺序执行模型规定CPU指令会依次执行,除非遇到分支改变流程。分支可分为条件分支和无条件分支,条件分支的执行取决于特定条件是否满足。直接分支的目标地址编码在指令中,而间接分支则依赖寄存器或内存中的值。分支预测通过预判分支结果来最小化延迟,这对优化CPU性能极为关键。简化if语句和循环中的条件复杂度,可通过减少不必要分支来提升性能。内联函数能消除与函数调用和返回相关的分支,从而提高执行效率。深层函数调用栈可能导致效率低下,尤其在使用返回地址栈的架构中。间接分支(如C++继承或函数指针引发)通常开销更大且更难预测。使用条件移动或选择指令可减少分支需求,从而优化代码执行。
Techniques to beat Arrays.hashCode(byte[]) using Java's own means10 months agohttps://www.dynatrace.com/news/blog/java-arrays-hashcode-byte-efficiency-techniq...Java的Arrays.hashCode(byte[])方法为字节数组计算32位哈希值OpenJDK 20及之前版本的默认实现采用简单循环,未进行高度优化循环展开和向量化技术(SWAR和SIMD)可显著加速哈希计算基于SWAR的实现通过64位长整型位操作,每次处理8个字节基于SIMD的实现利用Java向量API并行处理多个字节,性能超越内部实现基准测试显示:SWAR比默认实现快2.9倍,SIMD优于OpenJDK内部实现两种方法对非整倍数字节数组都会单独处理剩余字节研究表明这些技术可有效改进OpenJDK当前实现
A fast 3D collision detection algorithm10 months agohttps://cairno.substack.com/p/improvements-to-the-separating-axis文章讨论了针对凸多面体碰撞检测的分离轴测试(SAT)算法的改进方法。提出通过叠加高斯图来寻找闵可夫斯基差的面,从而减少对完整支撑函数计算的依赖。作者将寻找分离重叠凸集的最小平移量问题构建为一个非凸二次约束二次规划(QCQP)优化问题。对于凸多面体,支撑函数的特性允许高效遍历顶点区域来找到全局最小值,而无需重新计算支撑点。优化后的SAT测试涉及在球面上遍历弧线、跟踪支撑点,并在区域变化时更新它们,显著加快了碰撞检测速度。提供的演示表明,对于多面体模型,该方法比传统SAT快5-10倍,但在三角形处理方面仍存在一些数值问题。该方法被表述为球面上的优化问题,利用图遍历和支撑函数特性来提高计算效率。
Optimizing a Math Expression Parser in Rust10 months agohttps://rpallas.xyz/math-parser/Rust数学表达式解析器的基准实现耗时43.1秒优化1:消除词法分析阶段的向量分配,时间降至6.45秒(提升85%)优化2:直接从输入字节解析而非字符串,时间降至3.68秒(提升43%)优化3:移除Peekable迭代器,时间降至3.21秒(提升13%)优化4:实现多线程和SIMD并行处理,时间降至2.21秒(提升31%)优化5:采用内存映射I/O避免额外拷贝,时间降至0.98秒(提升56%)最终优化版本运行时间从初始43秒降至1秒以内
Windows 11 clean install guide: remove bloatware and optimize performance10 months agohttps://sym.bearblog.dev/win11-install/从互联网档案馆下载纯净版Windows 11(Tiny11)使用Rufus(Windows)或Balena Etcher(Linux/OSX)将ISO镜像写入U盘开机时连续按F2/F10/F12/ESC/DEL键进入BIOS,必要时需关闭快速启动安装Windows 11后,通过PowerShell运行Microsoft Activation Script激活系统使用Chris Titus工具精简Windows 11并安装Firefox/SumatraPDF/VLC等应用(可选)通过PowerShell的Invoke-WebRequest命令下载其他安装程序优化Firefox:安装Ublock Origin插件、启用所有过滤器并关闭遥测功能安装Microsoft Office(2007-2016版)并使用相同工具或提供的密钥激活免责声明:操作风险自担,务必提前做好数据备份
"high level" languages are easier to optimize10 months agohttps://jyn.dev/high-level-languages-are-easier-to-optimize/高级语言相比低级语言更容易优化低级语言由于复杂的别名分析和内存分配问题而难以优化Haskell的引用透明性使得流融合等优化更易实现像Futhark这样的函数式语言通过使用未装箱值和严格约束,能在特定领域超越C语言性能SQL的声明式特性允许在不修改源代码的情况下持续获得显著的性能提升原始指针有时对特定内存优化是必要的,但在通用编程中很少需要Rust通过将原始指针设为可选特性并支持函数式编程范式来优化,是朝着正确方向迈出的一步允许在语言间切换的元语言有助于选择最合适的工具,从而提升性能
Hill Space: Neural nets that do perfect arithmetic (to 10⁻¹⁶ precision)10 months agohttps://hillspace.justindujardin.com/神经网络在基础算术和离散选择任务上常常表现不佳。约束条件W = tanh(��) �� σ(M��)通过允许计算而非学习最优权重,实现了离散选择中的系统性可靠性。特定权重配置可生成机器精度的数学运算,包括矩阵乘法、指数基元及三角运算。该约束创建的希尔空间将无界学习权重映射到[-1,1]范围,引导优化朝向离散选择。论文探讨了希尔空间学习动力学、新基元框架、实验及实现细节。
Easy dynamic dispatch using GLIBC Hardware Capabilities10 months agohttps://www.kvr.at/posts/easy-dynamic-dispatch-using-GLIBC-hardware-capabilities...GLIBC 2.33+引入的硬件能力检测机制(hwcaps)支持通过加载最高CPU优化级别实现动态调度共享库可针对不同优化级别(如x86-64-v4/x86-64-v3/x86-64-v2)多次编译,并存放于对应子目录动态链接器/加载器会根据CPU能力选择最优版本,必要时自动回退到较低级别该技术能有效提升跨架构性能表现,如Debian在打包llama.cpp和whisper.cpp的ggml时采用此方案基础版库(x86-64-v1)存放于标准路径,确保非GLIBC系统或缺少hwcaps支持时的兼容性该方案同时兼容RUNPATH和LD_LIBRARY_PATH环境变量,可灵活适应多种部署场景
C++: zero-cost static initialization10 months agohttps://cofault.com/zero-cost-static.html在C和C++中,静态变量可以在函数作用域内定义,具有静态存储期。在C语言中,静态变量的初始化器必须是编译时常量,这些值会直接嵌入到二进制文件中。C++对静态变量有复杂的初始化规则,包括对块作用域变量进行动态初始化。C++中块作用域的静态变量在控制流首次经过其声明时初始化,并采用线程安全机制。访问静态变量会因保护检查和同步机制而产生额外开销。一种消除该开销的方法是利用链接器特性,在专用段中预初始化静态变量。该解决方案使用`__attribute__((section))`和链接器符号`__start_SECNAME`与`__stop_SECNAME`实现高效初始化。技术难点包括内联函数和模板成员中的段属性冲突,需要通过特殊方法解决。最终方案采用嵌入式汇编指令和唯一符号命名来避免冲突。该方法显著降低了访问开销,使块级静态变量效率与文件级变量相当。
Converting Integers to Floats Using Hyperfocus (2022)10 months agohttps://blog.m-ou.se/floats/这篇博客详细记录了作者实现比编译器内置转换更快的128位整数转64位浮点数的探索历程。最初尝试将整数转为字符串再解析为浮点数,最终转向更复杂的位操作方案。作者发现忽略了Rust内置的`as f64`转换功能,出于不服输的心理开始深入研究手动实现方法。文中详细解释了IEEE 754浮点数标准,包括符号位、指数位和尾数位的构成原理。手动转换过程需要处理零值等边界情况、确保正确舍入,并对位操作进行性能优化。通过应用无分支舍入和避免128位运算等优化手段,最终实现了更快的转换算法。基准测试显示最终实现的转换速度比Rust内置方法快近两倍。这项优化最终被合并到Rust编译器和.NET运行时中,体现了实际工程价值。
Optimizations That Aren't10 months agohttps://zeux.io/2010/11/29/optimizations-that-arent/优化不应为了优化而优化,否则会降低代码可读性并引入错误遵循结构化优化流程:确保代码正常工作 -> 精确测量性能 -> 验证是否符合需求 -> 记录结果 -> 实施优化 -> 重新验证每次优化前后必须进行性能分析,以确认改进效果并避免性能倒退一个COLLADA导出器的实际案例警示:未经性能分析的优化会导致算法复杂度暴增至平方级缺乏优化前后性能分析的改进是无效的,反而可能导致性能严重劣化
Using Uninitialized Memory for Fun and Profit10 months agohttps://research.swtch.com/sparse文章讨论了一种利用未初始化内存优化性能的编程技巧,尤其适用于稀疏集合场景。该技术能将特定操作从线性时间复杂度降至常数级,显著提升效率。关键参考文献包括Aho、Hopcroft和Ullman 1974年的著作,以及Jon Bentley 1986年出版的《编程珠玑》。Briggs与Torczon 1993年的论文详细阐述了使用'dense'和'sparse'双数组的实现方案。'sparse'数组对非集合元素可存储任意值而不影响算法正确性。成员检测、元素添加和集合清空等操作均被优化至常数时间复杂度。此方法特别适用于空间成本低、时间敏感且集合稀疏的应用场景。潜在问题包括未初始化内存的安全隐患,以及必须使用无符号整型避免计算错误。与位向量相比,该技术在操作速度上更具优势,但会占用更多内存空间。典型应用场景包括编译器活跃变量集和图遍历算法等领域。
A Different Way to Think about Plane Fitting10 months agohttps://www.tangramvision.com/blog/a-different-way-to-think-about-plane-fitting三维计算机视觉中的平面拟合是一个常见问题,通常采用主成分分析(PCA)来识别平面的法向量。PCA通过分析数据点的分布实现,其中最小特征值对应的特征向量即代表平面法向量。传统基于PCA的平面拟合对异常值敏感,因此需要采用RANSAC或鲁棒PCA等更稳健的方法。非线性最小二乘优化具有联合参数估计、加权输入和异常值剔除的鲁棒代价函数等优势。将平面拟合作为最小二乘问题优化时,需使用点对平面的代价函数,并受法向量单位长度约束。三维单位向量空间(S2)虽非李群,但仍可通过旋转群(SO3)参数化法向量进行优化。通过在SO3上优化并固定一个参数(绕标准向量的滚动角),问题可简化为无约束非线性最小二乘优化。鲁棒最小二乘拟合能有效处理异常值,相比传统方法提供更可靠的平面拟合结果。未来研究方向包括直接在S2空间进行优化(尽管其非李群特性),以探索更高效的平面拟合方案。
PSA: Collision Detection is an optimization problem and GJK is Frank-Wolfe10 months agohttps://cairno.substack.com/p/psa-collision-detection-is-an-optimization碰撞检测本质上是一个凸优化问题。GJK算法是Frank-Wolfe(FW)算法的一个特定子案例。2022年的一篇论文明确展示了GJK与FW之间的联系。GJK被广泛应用于现代游戏物理引擎,如PhysX、Bullet和Chaos。Frank-Wolfe是一种用于解决凸优化问题的通用迭代算法,于1956年提出。在游戏编程教学中,GJK的优化视角较少被强调。2022年的论文使用优化概念对GJK进行了直观解释。GJK维护一个单纯形的活跃集,提高了边界附近的精度。该论文包含易于理解的解释和代码示例。历史上,游戏开发者可能并未意识到GJK的FW推导过程。
Constrained languages are easier to optimize10 months agohttps://jyn.dev/constrained-languages-are-easier-to-optimize/现代低级语言由于复杂的别名分析和内存分配/释放机制而难以优化Haskell的引用透明性允许更轻松的优化(如流融合),而C语言则受困于指针别名问题函数式并行语言Futhark通过使用未装箱的固定大小整数和静态数组尺寸约束实现高性能SQL的声明式特性使其能随时间推移获得显著的性能提升(如Postgres基准测试所示)原始指针有时对特定内存优化是必要的,但在通用编程语言中应尽量减少使用Rust通过可选原始指针和函数式范式实现了优化友好的设计,代表着正确的发展方向未来属于能轻松实现专业语言互操作的元语言系统,这将带来最佳性能
Compressed Sensing10 months agohttps://en.wikipedia.org/wiki/Compressed_sensing压缩感知是一种通过求解欠定线性系统来高效获取和重构信号的信号处理技术。该技术通过优化利用信号稀疏性,能够以低于奈奎斯特-香农采样定理要求的样本量实现信号重建。重建的关键条件包括稀疏性(信号在某个域中必须稀疏)和非相干性(通过等距特性实现)。应用领域包括核磁共振成像(MRI),该场景通常满足非相干性条件,从而实现更快扫描和更低剂量成像。其理论根源可追溯至统计学(最小二乘法、L1范数)、稳健统计学及信号处理领域(地震学、匹配追踪算法)。压缩感知并不违背奈奎斯特-香农定理,而是为具有高频成分的稀疏信号提供了替代解决方案。主要方法涉及在稀疏约束下求解欠定系统,采用L1最小化或基追踪去噪技术以增强噪声鲁棒性。图像重建中采用全变分(TV)正则化方法,在降噪和消除伪影的同时保持边缘清晰度。迭代重加权L1最小化和边缘保持TV技术通过自适应惩罚系数与梯度来提升重建质量。方向性TV改进方案通过估计和优化方向场来提升精度,同时保留纹理和边缘特征。应用场景涵盖摄影(单像素相机)、全息成像、人脸识别、网络层析成像及天文观测(孔径合成)。在MRI中压缩感知可缩短扫描时间并保持图像质量,在CT中则能通过减少投影实现低剂量成像。
Dynamic programming bursting balloons10 months agohttps://sylhare.github.io/2025/07/29/bursting-balloons.html动态规划用于解决气球爆破问题,该问题需要通过策略性地爆破气球来最大化收集的金币数。由于气球爆破顺序存在依赖性,该问题无法使用贪心算法解决。动态规划的核心概念包括状态(问题配置)、基本情况(最简单实例)和状态转移(状态间的关系)。该问题被分解为多个子问题,每个子问题代表一个气球区间,并通过组合更小子问题的解来构建最终解。使用动态规划表存储每个子数组可获得的最大金币数,通过迭代或带备忘录的递归方式填充表格。状态转移函数通过将每个气球视为最后爆破的气球,并组合左右子数组的结果来计算区间最大金币数。解决方案涉及在气球数组两端填充虚拟气球(值为1)以处理边界情况。算法时间复杂度为O(n³)(三重嵌套循环),空间复杂度为O(n²)(动态规划表)。以气球数组[3,1,5]为例,演示了动态规划表的填充过程及最优路径的确定方法。
Complex Iterators Are Slow9 months agohttps://caolan.uk/notes/2025-07-31_complex_iterators_are_slow.cmTimi是一个纯JavaScript实现的B树,通过用回调替代迭代器,实现了业界领先的遍历速度。JavaScript迭代器在复杂遍历场景下天生较慢,因为它们阻碍了内联优化,这会显著影响性能。内联优化通过将函数调用替换为函数体来避免开销,从而提升性能。通过保持函数精简,可以促使V8的优化编译器TurboFan进行内联优化。Timi中的复杂遍历涉及沿树结构上下移动,这使得代码过于复杂而无法被内联。迭代器在每次循环中都隐藏了一个未内联的next()慢调用,而回调可以避免这个问题。回调允许将循环移入迭代器内部,实现内联优化并消除循环内的函数调用。基准测试表明,在复杂遍历场景下,迭代器API比回调API慢4倍。简单迭代器可以有良好性能,但复杂遍历可能需要手动使用回调进行优化。虽然迭代器、生成器和Promise的反转控制很强大,但在热点代码路径中需谨慎使用。