Int64针对32位架构是按照4字节还是8字节对齐?
作为构建.NET的标准,CLI Spec(ECMA-335)针对基元类型的对齐规则具有如下的描述。按照这个标准,我们是这么理解的:8字节的数据类型(int64、unsigned int64和float64)根据采用的机器指令架构选择4字节或者8字节对其。进一步来说,它们在x86/x64机器上的对其字节分别为4字节和8字节。
Built-in data types shall be properly aligned, which is defined as follows:
1-byte, 2-byte, and 4-byte data is properly aligned when it is stored at a 1-byte, 2-byte, or 4-byte boundary, respectively.
8-byte data is properly aligned when it is stored on the same boundary required by the underlying hardware for atomic access to a
native int.Thus,
int16andunsigned int16start on even address;int32,unsigned int32, andfloat32start on an address divisible by 4; andint64,unsigned int64, andfloat64start on an address divisible by 4 or 8, depending upon the target architecture. The native size types (native int,native unsigned int, and&) are always naturally aligned (4 bytes or 8 bytes, depending on the architecture). When generated externally, these should also be aligned to their natural size, although portable code can use 8-byte alignment to guarantee architecture independence. It is strongly recommended thatfloat64be aligned on an 8-byte boundary, even when the size ofnative intis 32 bits.
我们通过一个简单控制台程序来验证这个说法。为了在64位机器上模拟32位平台,我们按照如下的方式修改了.cspro文件,将PlatformTarget属性设置为x86(默认为Any CPU)。
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
<PlatformTarget>x86</PlatformTarget>
</PropertyGroup>
</Project>
在演示程序中,我们定义了如下一个名为Foobar的结构体Record。该结构体具有两个字段,类型分别为byte和ulong(unsigned int64)。我们将这两个字段分别设置为byte.Max(FF)和ulong.MaxValue(FF-FF-FF-FF-FF-FF-FF-FF-FF),并将在内存中的二进制形式输出来。为了进一步确定当前的环境与CLI Spec的描述一致,我们将Environment.Is64BitProcess属性(确定是不是64位处理器),ulong类型的字节数(确定这是一个”8-byte data”)和IntPtr.Size(确定native int类型的对其边界是4字节)。
unsafe
{
var bytes = new byte[sizeof(Foobar)];
var foobar = new Foobar(byte.MaxValue, ulong.MaxValue);
Marshal.Copy(new nint(Unsafe.AsPointer(ref foobar)), bytes, 0, bytes.Length);
Console.WriteLine(BitConverter.ToString(bytes));
Console.WriteLine($"Environment.Is64BitProcess = {Environment.Is64BitProcess}");
Console.WriteLine($"sizeof(ulong) = {sizeof(ulong)}");
Console.WriteLine($"IntPtr.Size = {IntPtr.Size}");
} public record struct Foobar(byte Foo, ulong Bar);
从如下的输出可以看出,当前的环境与CLI Spec描述的32位处理器架构是一致的,但是ulong类型的字段Bar采用的对其长度是8字节而不是4字节(如果采用4字节对其的话,二进制形式应该FF-00-00-00-FF-FF-FF-FF-FF-FF-FF-FF-FF)。

对于这个问题,我们目前尚未找到一个权威的答案,莫不是我对CLI Spec的解读有误?还是我们的验证程序有问题?希望对此熟悉的朋友不吝赐教!我们目前Google如下这些相关的说法:
Memory alignment on a 32-bit Intel processor
The usual rule of thumb (straight from Intels and AMD's optimization manuals) is that every data type should be aligned by its own size. An
int32should be aligned on a 32-bit boundary, anint64on a 64-bit boundary, and so on. A char will fit just fine anywhere.Another rule of thumb is, of course "the compiler has been told about alignment requirements". You don't need to worry about it because the compiler knows to add the right padding and offsets to allow efficient access to data.
WHY IS THE DEFAULT ALIGNMENT FOR `INT64_T` 8 BYTE ON 32 BIT X86 ARCHITECTURE?
Interesting point: If you only ever load it as two halves into 32bit GP registers, then 4B alignment means those operations will happen with their natural alignment.
However, it's probably best if both halves of the variable are in the same cache line, since almost all accesses will read / write both halves. Aligning to the natural alignment of the whole thing takes care of that, even ignoring the other reasons below.
32bit x86 can load 64bit integers in a single 64bit-load using MMX or SSE2
movq. Handling 64bit add/sub/shift/ and bitwise booleans using vector instructions is more efficient (single instruction), as long as you don't need immediate constants or mul or div. The vector instructions with 64b elements are still available in 32b mode.Atomic 64bit compare-and-exchange is also available in 32bit mode (
lock CMPXCHG8B m64works just like 64bit mode'slock CMPXCHG16B m128, using two implicit registers (edx:eax)). IDK what kind of penalty it has for crossing a cache-line boundary.Modern x86 CPUs have essentially no penalty for misaligned loads/stores unless they cross cache-line boundaries, which is why I'm only saying that, and not saying that misaligned 64b would be bad in general. See the links in the x86 wiki, esp. Agner Fog's guides.
Why is the "alignment" the same on 32-bit and 64-bit systems?
MSVC targeting 32-bit x86 gives
__int64a minimum alignment of 4, but its default struct-packing rules align types within structs tomin(8, sizeof(T))relative to the start of the struct. (For non-aggregate types only). That's not a direct quote, that's my paraphrase of the MSVC docs link from @P.W's answer, based on what MSVC seems to actually do. (I suspect the "whichever is less" in the text is supposed to be outside the parens, but maybe they're making a different point about the interaction on the pragma and the command-line option?)
Int64针对32位架构是按照4字节还是8字节对齐?的更多相关文章
- 32位系统和x86的关系?
32位操作系统针对32位CPU设计,cpu的位是指一次性可处理的数据量是多少,也等于寻址空间的大小或是通用寄存器的大小,一般数据总线的宽度也和cpu位数相同,但也有例外(如8088数据总线宽度为8然而 ...
- 32位嵌入式微处理器(processor)一览
32位嵌入式微处理器(processor)一览 由于嵌入式系统的专用型与定制性,与全球PC市场不同,没有一种微处理器或者微处理器公司可以主导嵌入式系统.本文分析了当前市场上主流的一些32位嵌入式微处理 ...
- Xubuntu 计划从 19.04 版本开始停止提供 32 位安装镜像(XDE/LXQt的 Lubuntu 成为了目前唯一仍然提供 32 位安装镜像的 Ubuntu 桌面发行版)
Ubuntu 17.10 以及其他许多 *buntu 衍生品都已在今年早些时候停止提供 32 位安装镜像.但其中有一个依然坚持提供适用于 i386 架构的镜像,它就是 Xubuntu,但现在 Xubu ...
- iOS-程序发布-32位和64位系统的兼容
在苹果推出iPhone5S时,64位的应用就走到了眼前.当时就看见苹果官方资料宣布iOS7.x的SDK支持了64位的应用,而且内置的应用都已经是64位. 我记得自己刚刚接触电脑时还有16位的系统,指针 ...
- iOS上应用如何兼容32位系统和64位系统
在苹果推出iPhone5S时,64位的应用就走到了眼前.当时就看见苹果官方资料宣布iOS7.x的SDK支持了64位的应用,而且内置的应用都已经是64位. 我记得自己刚刚接触电脑时还有16位的系统,指针 ...
- iOS如何兼容的应用程序32位系统和64Bit系统
苹果发布iPhone5S时刻,64应用程序位去了眼前.当时我看到苹果公布的官方数据iOS7.x的SDK支撑64位应用程序.而内置的应用程序已经64位置. 我记得自己刚刚接触电脑时还有16位的系统,指针 ...
- IPHONE 64位和32位
参考段一:iPhone 5没有64位的,只有32位架构,苹果是从iPhone 5s开始对全线移动产品使用64位架构.iPhone 5s发布之后的所有产品都是64位的使用LUAJIT或LUAC都可以对L ...
- 介绍 32 位和 64 位版本的 Microsoft Office 2010
在使用 64 位版本的 Office 2010 运行现有解决方案时存在两个基本问题: Office 2010 中的本机 64 位进程无法加载 32 位二进制文件.在使用现有 Microsoft Act ...
- C++:基础篇-32位和64位系统区别及字节数
今儿面试了一个刚刚毕业的,但是不知道一个int.long.double这几个都是多少位,我给你们总结一下哈: 常用数据类型对应字节数 可用如sizeof(char),sizeof(char*)等得出 ...
- ASM:《X86汇编语言-从实模式到保护模式》第10章:32位x86处理器的编程架构
★PART1:32位的x86处理器执行方式和架构 1. 寄存器的拓展(IA-32) 从80386开始,处理器内的寄存器从16位拓展到32位,命名其实就是在前面加上e(Extend)就好了,8个通用寄存 ...
随机推荐
- 从零开始基于Archlinux 安装 containerd + k8s
下载ISO文件:https://mirrors.tuna.tsinghua.edu.cn/archlinux/iso/latest/ 目录 1. 准备工作 2. 磁盘管理 2.1 磁盘分区 2.2 磁 ...
- dataX源码学习
文章目录 前言 开始准备 运行配置 开始运行 JobContainer 1.进入init prepare schedule post阶段 this.invokeHooks(); 总结 前言 在用dat ...
- 关于java中的equal
正常情况下的equal方法是比较两者之间的id.如果需要它实现其他的问题,可以通过重写这个方法.idea自带了重写equal的快捷方式.右键生成中的equals() 和 hashCode()就可以帮助 ...
- NC54585 小魂和他的数列
题目链接 题目 题目描述 一天,小魂正和一个数列玩得不亦乐乎. 小魂的数列一共有n个元素,第i个数为Ai. 他发现,这个数列的一些子序列中的元素是严格递增的. 他想知道,这个数列一共有多少个长度为K的 ...
- 做了个vscode 小插件,用于修改window 的颜色以区分同时打开的不同工作区,快用起来吧!
Coralize marketplace/coralize 以高效且便捷的方式自定义Visual Studio Code工作区窗口的状态栏.标题栏以及活动边栏等颜色!这将对那些需要同时打开多个vsco ...
- Hardhat 开发框架 - Solidity开发教程连载
Decert.me 要连载教程了, <Solidity 开发教程> 力求系统.深入的介绍 Solidity 开发, 同时这是一套交互式教程,你可以实时的修改教程里的合约代码并运行. 本教程 ...
- 获取android app 的Activity 和 Package
开头 appium 配置, sdk 配置,jdk配置,adb配置,python配置是我们app 自动化测试必不可少的配置,当然这种配置网上有很多,我们在这里就不展开说了. 直接就开始自动化脚本的dem ...
- 2023-03-13:给定一个整数数组 A,坡是元组 (i, j),其中 i < j 且 A[i] <= A[j], 这样的坡的宽度为 j - i。 找出 A 中的坡的最大宽度,如果不存在,返回 0
2023-03-13:给定一个整数数组 A,坡是元组 (i, j),其中 i < j 且 A[i] <= A[j], 这样的坡的宽度为 j - i. 找出 A 中的坡的最大宽度,如果不存在 ...
- 2021-01-05:mysql的自增id的实现逻辑是什么样子的?
福哥答案2021-01-05:答案来自这个链接:[ 每日一面 - mysql 的自增 id 的实现逻辑是什么样子的?](https://zhanghaoxin.blog.csdn.net/articl ...
- 2021-02-17:规定1和A对应、2和B对应、3和C对应...26和Z对应,那么一个数字字符串比如"111”就可以转化为:"AAA"、"KA"和"AK"。给定一个只有数字字符组成的字符串str,请问有多少种转化结果?
2021-02-17:规定1和A对应.2和B对应.3和C对应...26和Z对应,那么一个数字字符串比如"111"就可以转化为:"AAA"."KA&qu ...