2411rust,正与整128
原文
长期以来,Rust
在x86-32
和x86-64
架构上128
位整数的对齐
与C语言
不一致.最近已解决此问题
,但该修复
带来了一些值得注意
的效果
.
作为用户,除非如下,否则不用担心:
1,假设i128/u128
对齐,而不是用align_of
2,忽略improper_ctypes*
检查,并在FFI
中使用这些类.
除x86-32
和x86-64
外,其他架构
不变.如果你的代码大量使用128
位整数,会注意到运行时性能
提高,但可能会增加内存使用
.
背景
数据类型
有两个与内存
中的排列方式
有关的内部值
:大小和对齐
.类型的大小
是它在内存
中消费的空间量
,对齐
指定了允许在哪些地址放置它
.
像原语
此类简单类型
的大小
一般是无歧义
的,是它们所表示的数据
的没有填充(未使用的空间)
的确切大小
.如,i64
的大小总是为64
位或8字节
.
但是,对齐
可能会有所不同.可在(1字节对齐
)任意内存地址
中保存8字节整数
,但大多数64
位计算机如果按8的倍数(8字节对齐)
保存,则会取得最佳性能
.
因此,与其他语言
一样,Rust
中的原语
默认有该最有效的对齐
.在创建复合类型
时可见该效果:
use core::mem::{align_of, offset_of};
#[repr(C)]
struct Foo {a: u8, //1字节对齐b: u16, //2字节对齐
}
#[repr(C)]
struct Bar {a: u8, //1字节对齐b: u64, //8字节对齐
}
println!("Offset of b (u16) in Foo: {}", offset_of!(Foo, b));
println!("Alignment of Foo: {}", align_of::<Foo>());
println!("Offset of b (u64) in Bar: {}", offset_of!(Bar, b));
println!("Alignment of Bar: {}", align_of::<Bar>());
输出:
`Foo`中`b(u16)`的偏移:2`Foo`对齐:2`栏`中`b(u64)`的偏移:8`bar`对齐:8
看到,在一个结构
中,总是在它的偏移
是其对齐的倍数
位置放置一个类型
,即使表明未使用的空间
,当不使用repr(C)
时,Rust
默认最小化它.
这些数字
不是任意的;应用二进制接口
(ABI
)说明了它们应该是什么
.在系统V
(Unix&Linux
)的x86-64psABI
(处理器相关的ABI
)中,图3.1
:标量类型
准确地告诉了应该如何表示原语
:
C型 | Rust 等价 | sizeof | 对齐(字节) |
---|---|---|---|
符 | i8 | 1 | 1 |
正符 | u8 | 1 | 1 |
短 | i16 | 2 | 2 |
正短 | u16 | 2 | 2 |
长 | i64 | 8 | 8 |
正长 | u64 | 8 | 8 |
ABI
仅指定了C类型
,但Rust
在兼容和性能优势方面
都遵守相同定义
.
错误的对齐问题
如果两个实现
在数据类型
的对齐
上有分歧,则无法可靠
地共享包含该类型的数据
.Rust
对128
位类型的对齐
不一致:
println!("alignment of i128: {}", align_of::<i128>());
//`rustc1.76.0`版本
// `i128`对齐:8
printf("alignment of __int128: %zu\n", _Alignof(__int128));
//`GCC`版本`13.2`
// __int128对齐:16
// Clang17.0.1
// __int128对齐:16
回头看一下psABI
,可见Rust
在此的对齐
是错误的:
C型 | Rust 等价 | sizeof | 对齐(字节) |
---|---|---|---|
__int128 | i128 | 16 | 16 |
正__int128 | u128 | 16 | 16 |
表明,这并不是因为Rust
积极地做错
了什么:原语
的布局
来自Rust
和Clang
等语言使用的LLVMcodegen
后端,且它有硬编码
为8字节
的i128
对齐.
Clang
使用正确的对齐
只是因为变通,即在把类型交给LLVM
前,手动按16
字节设置对齐
.这解决
了布局问题
,但也是其他一些小问题的根源
.
Rust
无此手动调整,因此在https://github.com/rustlang/rust/issues/54341
上报告了它
.
调用约定问题
还有一个问题
:LLVM
在按函数参数
传递128
位整数时,并不总是正确
.在发现它与Rust
相关前,这是LLVM
中的一个已知问题
.
调用函数
时,会在寄存器
中传递参数
,直到没有更多的槽
,然后会"溢出"
到栈中(程序的内存
).
ABI
在3.2.3
传递参数一节中,也告诉了该怎么做
:
__int128
类型的参数
与INTEGER
操作相同
,但它们不适合一个通用寄存器
,而是需要两个寄存器
.为了分类,按如下
实现对待__int128
:
typedef struct {long low, high;
} __int128;
但在内存中保存
的__int128
类型的参数
必须在16
字节边界
上对齐
.
可手动实现调用约定
来试此操作.在下面C示例
中,用内联汇编
按val
为0x11223344556677889900aabbccddeeff
值,来调用foo(0xaf,val,val,val)
.
x86-64
使用RDI,RSI,RDX,RCX,R8
和R9
寄存器,来按顺序
传递函数参数
.每个寄存器
适合一个字(64位
),不合适的都压进
栈中.
/*`<https://godbolt.org/z/5c8cb5cxs>`的完整示例*/
/*要查看问题,需要一个`内边距`值来"搞砸"参数对齐*/
void foo(char pad, __int128 a, __int128 b, __int128 c) {printf("%#x\n", pad & 0xff);print_i128(a);print_i128(b);print_i128(c);
}
int main() {asm(/*`加载`适合`寄存器`的参数*/"movl $0xaf,%edi\n\t"/*第1个槽位`(EDI)`:填充符(`"EDI"`是*与`"RDI"`相同,只是访问大小较小)*/"movq $0x9900aabbccddeeff,%rsi\n\t"/*第2个槽`(RSI):"a"`的下半部分*/"movq $0x1122334455667788,%rdx\n\t"/*第3个槽`(RDX):"a"`的上半部分*/"movq $0x9900aabbccddeeff,%rcx\n\t"/*第4个槽`(RCX):"b"`的下半部分*/"movq $0x1122334455667788,%r8\n\t"/*第5个槽位`(r8):'b'`的上半部分*/"movq $0xdeadbeef4c0ffee0,%r9\n\t"/*第6个槽`(R9)`:应该未使用,但来欺骗`Clang`!*//*重用保存的`寄存器`来加载栈*/"pushq %rdx\n\t"/*在栈上传递`'c'`的上半部分*/"pushq %rsi\n\t"/*在栈上传递`'c'`的下半部分*/"call foo\n\t"/*调用函数*/"addq $16,%rsp\n\t"/*重置栈*/);
}
使用GCC
运行上述操作打印以下期望输出:
0xaf0x11223344556677889900aabbccddeeff0x11223344556677889900aabbccddeeff0x11223344556677889900aabbccddeeff
但是使用Clang17
打印:
0xaf0x11223344556677889900aabbccddeeff0x11223344556677889900aabbccddeeff0x9900aabbccddeeffdeadbeef4c0ffee0^^^^^^^^^^^^^^^^这应该是下半部分^^^^^^^^^^^^^^^^很熟悉
惊喜!
这说明了第二个问题:LLVM
期望i128
在可能时一半在寄存器
中传递,一半在栈
上传递,但ABI
禁止这样做
.
因为该行为来自LLVM
且没有合理的解决方法
,因此这在Clang
和Rust
中都是一个问题
.
方法
NikitaPopov
修复了D158169
的调用约定问题.这两项更改
都已纳入LLVM18
,即所有相关的ABI
问题都使用在此版本
的Clang
和Rust
中得到解决.
因为这些更改
,Rust
现在生成正确的对齐
:
println!("alignment of i128: {}", align_of::<i128>());
//`rustc1.77.0`版本
i128
对齐:16
如上,ABI
指定数据类型对齐
的部分原因
是因为它在该架构
上效率更高
.更改手动对齐
的初始性能
运行,表明大大改进了编译器性能
(严重依赖128
位整数来处理整数文字).
增加对齐
的缺点是在内存中复合类型
并不总是很好地组合
在一起,从而导致使用量增加
.可惜,即需要牺牲一些性能优势
,以避免增加内存成本
.
兼容
总之,使用LLVM18
(默认版本从1.78
开始)的Rust
的i128
和u128
将与版本的GCC
及Clang18
及更高版本
(2024
年3月发布)完全兼容
.
相关文章:
2411rust,正与整128
原文 长期以来,Rust在x86-32和x86-64架构上128位整数的对齐与C语言不一致.最近已解决此问题,但该修复带来了一些值得注意的效果. 作为用户,除非如下,否则不用担心: 1,假设i128/u128对齐,而不是用align_of 2,忽略improper_ctypes*检查,并在FFI中使用这些类. 除x86-32和x86-64…...
将 HTML 转换为 JSX:JSX 和 JSX 规则
JSX 是 JavaScript 的语法扩展。您可以在 JavaScript 文件中编写 HTML 格式。 它基于 Web、Html、Css 和 JavaScript。Web 开发人员将页面内容分别编写为 Html 文件,将设计编写为 Css 文件,将逻辑编写为 JavaScript 文件。 须知 : JSX 是一个…...
将 FastAPI 部署到生产服务器(一套 全)
将 FastAPI 部署到生产服务器(全) 文章目录 将 FastAPI 部署到生产服务器(全)一、前言二、Fastapi项目 生产环境配置1. 准备环境2. 编写 FastAPI 应用3. 使用 Uvicorn 运行应用4. 配置生产级服务器 Gunicorn4.1 配置 Gunicorn 和 …...
题解 洛谷 Luogu P1873 [COCI 2011/2012 #5] EKO / 砍树 二分答案 C/C++
题目传送门: P1873 [COCI 2011/2012 #5] EKO / 砍树 - 洛谷 | 计算机科学教育新生态https://www.luogu.com.cn/problem/P1873思路: 很简单的二分答案 每次找区间中点 m,判断以 m 为高度砍下的木头是否够 h 即可 代码: #defin…...
SpringCloud SaToken整合微服务 集成Redis 网关路由权限拦截 服务间内部调用鉴权
介绍 作为 API 网关,通常负责路由、负载均衡、安全控制等功能。进行 统一鉴权 的做法意味着将所有微服务的认证和授权逻辑集中到网关层,而不是每个微服务单独实现。这样做有许多好处,微服务只关心核心业务逻辑,不需要处理身份验证…...
Oracle ADB 导入 BANK_GRAPH 的学习数据
Oracle ADB 导入 BANK_GRAPH 的学习数据 1. 下载数据2. 导入数据运行 setconstraints.sql 1. 下载数据 访问 https://github.com/oracle-quickstart/oci-arch-graph/tree/main/terraform/scripts,下载, bank_accounts.csvbank_txns.csvsetconstraints.…...
优化 MFC CGridCtrl 的表格布局与功能
在使用 MFC 的 CGridCtrl 控件创建表格时,遇到的一个典型问题是,当表格滚动条出现时,最后一列会显示空白。这篇博客将记录解决这一问题的详细过程,同时总结了 CGridCtrl 初始化及优化的关键步骤,帮助开发者快速搭建一个…...
koa-body 的详细使用文档
目录 koa-body install Features Hello World - Quickstart Usage with koa-router Usage with unsupported text body type Options 关于 parsedMethods 的说明 文件支持 关于未解析请求主体的说明 一些强大的选择 使用总结 koa-body 功能齐全的 koa body 解析器中…...
信息系统与互联网中的安全、隐私及伦理问题
1 伦理(Ethics) 1.1 伦理框架(Ethical Frameworks) 自然法与权利(Natural Law and Rights) 定义:基于人类自然权利的伦理思想,强调生命、自由和财产等基本权利。应用:隐…...
Java安全—log4j日志FastJson序列化JNDI注入
前言 log4j和fastjson都是这几年比较火的组件,前者是用于日志输出后者则是用于数据转换,今天我们从源码来说一下这两个组件为何会造成漏洞。 实验环境 这里的idea要进行一下配置,因为我们要引用第三方组件,而这些第三方组件都是…...
【STM32开发笔记】移植AI框架TensorFlow到STM32单片机【DSP指令加速篇】
【STM32开发笔记】移植AI框架TensorFlow到STM32单片机【DSP指令加速篇】 一、前文回顾二、CMSIS-NN简介2.1 为什么介绍CMSIS-NN?2.2 CMSIS-NN是什么?2.3 CMSIS-NN核心特性2.4 CMSIS-NN算子支持 三、TFLMCMSIS-NN集成3.1 包含TFLM的STM32项目3.2 理解TFLM…...
Python中如何判断一串文本是不是数字
目录 1. 内置函数2. 尝试类型转换3. 正则表达式 在编程中,我们经常需要确定一段文本是否为数字。 这不仅关系到数据的准确性,还涉及到后续的计算和处理。 1. 内置函数 在Python中,可以使用str.isdigit()、str.isnumeric()和str.isdecimal()…...
基于YOLOv8深度学习的智慧农业山羊行为检测系统研究与实现(PyQt5界面+数据集+训练代码)
随着智慧农业的快速发展,利用先进的技术手段对牲畜的行为进行自动化监测和管理,已经成为现代农业中的重要研究方向之一。在传统的农业管理模式中,牲畜的行为监测通常依赖于人工观测,耗时耗力且难以实现大规模实时监控。然而&#…...
Redis环境部署(主从模式、哨兵模式、集群模式)
一、概述 REmote DIctionary Server(Redis) 是一个由 Salvatore Sanfilippo 写的 key-value 存储系统,是跨平台的非关系型数据库。Redis 是一个开源的使用 ANSI C 语言编写、遵守 BSD 协议、支持网络、可基于内存、分布式、可选持久性的键值对(Key-Value)存储数据库…...
高阶C语言之六:程序环境和预处理
本文介绍程序的环境,在Linux下对编译链接理解,较为简短,着重在于编译的步骤。 C的环境 在ANSI C(标准C语言)的任何一种实现中,存在两个不同的环境。 翻译环境:在这个环境中,源代码…...
Vue 3 国际化 (i18n) 最佳实践指南
1. 安装依赖 npm install vue-i18n@9 2. 项目结构建议 src/ ├── i18n/ │ ├── index.ts # i18n 配置文件 │ ├── languages/ # 语言文件目录 │ │ ├── zh-CN.ts # 中文 │ │ ├── en-US.ts # 英文 │ │ └─…...
Acme PHP - Let‘s Encrypt
Lets Encrypt是一个于2015年三季度推出的数字证书认证机构,旨在以自动化流程消除手动创建和安装证书的复杂流程,并推广使万维网服务器的加密连接无所不在,为安全网站提供免费的SSL/TLS证书。 使用PHP来更新证书: Acme PHP | Rob…...
获取DOM 节点的四大方式
前言: 在 Vue 中,获取 DOM 节点可以通过多种方式,如自定义属性、ref 引用、类选择器和 ID 选择器等。 一、使用 ref 获取 DOM 实例 ref 是 Vue 中推荐的获取 DOM 节点的方式,它为每个节点分配一个唯一的引用,可以直…...
ROS2 Humble 机器人建模和Gazebo仿真
一.Ubuntu22.04系统虚拟机安装 1.下载镜像并安装 Index of /ubuntu-releases/ | 清华大学开源软件镜像站 | Tsinghua Open Source Mirror 2.安装选英文版,安装类型选清除磁盘。 3.遇到无法复制windows内容到虚拟机里。需安装VMware tools。VMware tools安装不了&a…...
docker容器镜像的制作、使用以及传递
目录 制作容器镜像使用Dockerfile制作镜像准备所需文件构建镜像怎么不使用基础镜像来构建容器镜像 使用容器镜像传递容器镜像 这篇文章讨论一下怎么使用docker制作容器镜像,容器镜像的使用,以及怎么传递容器镜像。 制作容器镜像 docker制作容器镜像推荐…...
一种由于吸入硅酸盐粉尘而引起的肺部疾病:pneumonoultramicroscopicsilicovolcanoconiosis
有人说,pneumonoultramicroscopicsilicovolcanoconiosis是英语中最长的单词,这是一个医学词汇,意思是指:一种由于吸入硅酸盐粉尘而引起的肺部疾病。 pneumonoultramicroscopicsilicovolcanoconiosis [ˈnju:mənəuˌʌltrəˌmai…...
百度AI人脸检测与对比
1.注册账号 打开网站 https://ai.baidu.com/ ,注册百度账号并登录 2.创建应用 3.技术文档 https://ai.baidu.com/ai-doc/FACE/yk37c1u4t 4.Spring Boot简单集成测试 pom.xml 配置: <!--百度AI--> <dependency> <groupId>com.baidu.…...
贴代码框架PasteForm特性介绍之outer,outers,object,objects,outerdisplay
简介 PasteForm是贴代码推出的 “新一代CRUD” ,基于ABPvNext,目的是通过对Dto的特性的标注,从而实现管理端的统一UI,借助于配套的PasteBuilder代码生成器,你可以快速的为自己的项目构建后台管理端!目前管…...
sql数据库-权限控制-DCL
目录 常用权限类别 查询用户权限 举例 授予用户权限 删除权限 常用权限类别 权限说明ALL,ALL PRIVILEGES所有权限SELECT查询数据INSERT插入数据UPDATE修改数据DELETE删除数据ALTER修改表DROP删除数据库/表/视图CREATE创建数据库/表 查询用户权限 show grants for 用户名…...
【计组笔记】目录
【计组笔记】机器数表示及运算https://blog.csdn.net/Resurgence03/article/details/142673325?sharetypeblog&shareId142673325&sharereferAPP&sharesourceresurgence03&sharefromlink 【计组笔记】指令系统https://blog.csdn.net/Resurgence03/article/det…...
深度学习中的Pixel Shuffle和Pixel Unshuffle:图像超分辨率的秘密武器
在深度学习的计算机视觉任务中,提升图像分辨率和压缩特征图是重要需求。Pixel Shuffle和Pixel Unshuffle是在超分辨率、图像生成等任务中常用的操作,能够通过转换空间维度和通道维度来优化图像特征表示。本篇文章将深入介绍这两种操作的原理,…...
AntFlow 0.11.0版发布,增加springboot starter模块,一款设计上借鉴钉钉工作流的免费企业级审批流平台
AntFlow 0.11.0版发布,增加springboot starter模块,一款设计上借鉴钉钉工作流的免费企业级审批流平台 传统老牌工作流引擎比如activiti,flowable或者camunda等虽然功能强大,也被企业广泛采用,然后也存着在诸如学习曲线陡峭,上手难度大&#x…...
golang操作mysql基础驱动github.com/go-sql-driver/mysql使用
golang中类似java操作mysql的jdbc一样,github.com/go-sql-driver/mysql也为go提供了基础接口,在开发中往往需要写更多的代码来满足自己的定制需求,java在驱动基础上有了扩展,orm框架诞生,mybatis、jpa等都是好用的扩展…...
正则表达式完全指南,总结全面通俗易懂
目录 元字符 连接符 限定符 定位符 修饰符(标记) 运算符优先级 普通字符集及其替换 零宽断言 正向先行断言 负向先行断言 正向后发断言 负向后发断言 捕获组 普通捕获组 命名捕获组 PS:非捕获组 正则表达式在线测试: 正则在线测试工具 …...
运维面试题.云计算面试题之三ELK
1.ELK是什么? ELK 其实并不是一款软件,而是一整套解决方案,是三个软件产品的首字母缩写 Elasticsearch:负责日志检索和储存 Logstash:负责日志的收集和分析、处理 Kibana:负责日志的可视化 这三款软件都是开源软件,通常是配合使用,而且又先后归于 Elastic.co 公司名下,…...
seo搜索引擎优化总结报告/seo全网优化推广
问题描述 轮盘游戏来自赌场,轮盘上面平均分成若干个小的扇形,每个扇形上都有一个数字,流传较广的轮盘数字布局有“欧式规则”和“美式规则”两种。当 2 < n < 36时,求连续 n 个数字的和最大值的数字排列情况,以…...
hexo与 wordpress/网络营销的含义
本文翻译的内容为CodeSmith控制台指南。很多人仅仅知道CodeSmith像一个图形应用程序,或者可能是一个Visual Studio的附件,但是通过CodeSmith的控制台应用程序还有好多其他的使用方法。控制台应用程序是很有价值的,因为可以通过它去生成脚本&a…...
制作网站需要多少时间/天津做网站的网络公司
想过来写点日记的。。 现在发现博客也蛮好的。 有时候很想倾诉一下东西,而博客就给了平台 那些倾诉的,不想任何人知道。 一个陌生的平台,陌生的写着。转载于:https://blog.51cto.com/jinxin/981384...
招生网站建设策划方案/营销运营主要做什么
如果你还没有安装好SciTE,可以参考《在ubuntu 12.04 中安装SciTE 文本编辑器》。刚安装好的SciTE文本编辑器非常简朴,需要经过适当配置才能成为真正称手的编程利器。下文中的所有配置项,可以直接拷贝,然后粘贴到SciTE的用户设置文…...
网页的制作教案/手机seo快速排名
本文我们就来探索一下 Docker 的神秘世界,从零到一掌握 Docker 的基本原理与实践操作。别再守着前端那一亩三分地,是时候该开疆扩土了。 讲个故事 为了更好的理解 Docker 是什么,我们先来讲个故事: 我需要盖一个房子,于…...
网站 做百度推广有没有效果/搜索引擎优化的方法有哪些?
How I Trie to Make Spelling Suggestions http://blog.afterthedeadline.com/2010/01/29/how-i-trie-to-make-spelling-suggestions/ How to Write a Spelling Corrector http://norvig.com/spell-correct.html...