处理小于 cpu 数据总线的数据类型。 (c++ 转换为机器代码。)
Dealing with data types smaller than the cpu data bus. (c++ into machine code.)
在下面的回答中:https://softwareengineering.stackexchange.com/a/363379/370129
CPU访问内存的方式解释得非常清楚。假设我们创建一个小于 CPUs 数据总线的数据类型——因为是一个 c++ 字符;由 CPU 读取的数据总线大小的内存块如何修改为在寄存器中用作预期类型?如果指定的字节不存在,它是否被移位以占据寄存器中的最低有效字节?那么多余的(根据类型大小)最重要的字节是否设置为0?
然后 CPU 可以将 a/many 修改后的个体 byte/s 写入 a/many 内存 address/es 还是必须写入整个总线大小 chunk/s到are/is占用的bus-size内存slot/s被byte/s占用?
对于发生的事情,处理器非常具体。有些有多种选择。加载字节指令的常见选项是将高位置零或对高位进行符号扩展。因此,将 0xAB 加载到 32 位寄存器中(如果您的处理器具有该寄存器)将是 0x000000AB 或 0xFFFFFFAB,具体取决于。一些处理器以其他方式解决该问题。
cpu 总线的工作方式由 CPU 决定。如果您没有 load/store 字节(load/store 半字,load/store 字)指令,您的处理器将不会非常成功。但是有不同的方法来实现总线,正如 x86 和其他随着时间的推移而发展的那样。出于性能原因,今天您通常需要 32 或 64 或更宽的总线,平衡太大会带来很大的损失,太小会限制性能。不是必需的,但我们通常有 L1 缓存,有时还有 L2,缓存有多种原因,但缓存是固定宽度,例如 32 位或 64 位,因此较小的传输需要读-修改-写用于写入该 sram。这不是处理器问题,也不是总线上要解决的问题,bus/memory 控制器将捕获写入信息(地址和数据以及大小),然后处理另一侧的 sram 或总线。
读取通常由 cpu 处理,如果您在 32 位或 64 位总线上执行 8 位读取,那么结果将返回到总线定义的字节通道,然后处理器从指示从总线上取多少数据,在总线上的位置以及如何处理它(直接进入 alu,进入寄存器,对其进行符号或零扩展等)。
因为目标端往往是专为这条总线设计的缓存或外设,所以读不一定要设计为指示子总线大小,它们的长度往往以总线宽度为单位,所以32 位总线上的 128 位传输的长度为 4,开销发生在总线之间,然后理想情况下,四个时钟的突发将移动数据(与每次传输的所有开销相比,四个 32 位传输)。但是单个或较小尺寸的读取只会显示为单个宽度读取,并且处理器会隔离感兴趣的字节。
对于写入,通常有一个长度指示器或一个字节掩码,如果它是一个 32 位宽的总线,分为 4 个字节通道,那么会有一个 4 位掩码来向另一端指示一个字节的哪些字节write 是有效的,哪些不是 use/apply,这将根据需要驱动读取-修改-写入。例如,如果在手臂上你做了一个带有三个寄存器的 stm,而你的核心正在使用 64 位宽的总线,那么它会显示为两次传输,一个 32 位和一个 64 位,如果它使用 32 位宽的总线,那么它会可能是长度为三的单个传输。 (虽然我已经看到 arm 总线不会写入长度超过总线宽度的 2 个)。
对于较小的传输总是有惩罚,这取决于您是否可以看到它,而不是基于其他 processor/system 开销。由于开销,您不一定会看到 x86 的惩罚,但有时您可以看到一个 arm,进行四个字节大小的传输与一个 32 位传输,甚至两个 16s 与一个 32 位传输。但这取决于,这并不自动意味着你会看到它,这只是意味着你可能会看到。并且了解arm制造内核而不是芯片,因此芯片的大部分与arm无关但整体性能与芯片供应商而非arm有很大关系。
编辑
第二次尝试。
对于写入,cpu 总线通常支持 Fuz 指示的各种大小。 CPU(处理器核心)如今不必处理发生在远端的读取-修改-写入。
对于读取,cpu 总线通常会读取完整的总线宽度,处理器确实需要处理它。但是总线和处理器被设计成一个系统。取决于指令的处理器将提取正确数量的位数,并对它们进行零填充或符号扩展。
这在很大程度上取决于 processor/chip。
我已经看到,根据指令、总线、地址、大小,单个指令 can/may 变成多个总线事务是有道理的。
在下面的回答中:https://softwareengineering.stackexchange.com/a/363379/370129
CPU访问内存的方式解释得非常清楚。假设我们创建一个小于 CPUs 数据总线的数据类型——因为是一个 c++ 字符;由 CPU 读取的数据总线大小的内存块如何修改为在寄存器中用作预期类型?如果指定的字节不存在,它是否被移位以占据寄存器中的最低有效字节?那么多余的(根据类型大小)最重要的字节是否设置为0?
然后 CPU 可以将 a/many 修改后的个体 byte/s 写入 a/many 内存 address/es 还是必须写入整个总线大小 chunk/s到are/is占用的bus-size内存slot/s被byte/s占用?
对于发生的事情,处理器非常具体。有些有多种选择。加载字节指令的常见选项是将高位置零或对高位进行符号扩展。因此,将 0xAB 加载到 32 位寄存器中(如果您的处理器具有该寄存器)将是 0x000000AB 或 0xFFFFFFAB,具体取决于。一些处理器以其他方式解决该问题。
cpu 总线的工作方式由 CPU 决定。如果您没有 load/store 字节(load/store 半字,load/store 字)指令,您的处理器将不会非常成功。但是有不同的方法来实现总线,正如 x86 和其他随着时间的推移而发展的那样。出于性能原因,今天您通常需要 32 或 64 或更宽的总线,平衡太大会带来很大的损失,太小会限制性能。不是必需的,但我们通常有 L1 缓存,有时还有 L2,缓存有多种原因,但缓存是固定宽度,例如 32 位或 64 位,因此较小的传输需要读-修改-写用于写入该 sram。这不是处理器问题,也不是总线上要解决的问题,bus/memory 控制器将捕获写入信息(地址和数据以及大小),然后处理另一侧的 sram 或总线。
读取通常由 cpu 处理,如果您在 32 位或 64 位总线上执行 8 位读取,那么结果将返回到总线定义的字节通道,然后处理器从指示从总线上取多少数据,在总线上的位置以及如何处理它(直接进入 alu,进入寄存器,对其进行符号或零扩展等)。
因为目标端往往是专为这条总线设计的缓存或外设,所以读不一定要设计为指示子总线大小,它们的长度往往以总线宽度为单位,所以32 位总线上的 128 位传输的长度为 4,开销发生在总线之间,然后理想情况下,四个时钟的突发将移动数据(与每次传输的所有开销相比,四个 32 位传输)。但是单个或较小尺寸的读取只会显示为单个宽度读取,并且处理器会隔离感兴趣的字节。
对于写入,通常有一个长度指示器或一个字节掩码,如果它是一个 32 位宽的总线,分为 4 个字节通道,那么会有一个 4 位掩码来向另一端指示一个字节的哪些字节write 是有效的,哪些不是 use/apply,这将根据需要驱动读取-修改-写入。例如,如果在手臂上你做了一个带有三个寄存器的 stm,而你的核心正在使用 64 位宽的总线,那么它会显示为两次传输,一个 32 位和一个 64 位,如果它使用 32 位宽的总线,那么它会可能是长度为三的单个传输。 (虽然我已经看到 arm 总线不会写入长度超过总线宽度的 2 个)。
对于较小的传输总是有惩罚,这取决于您是否可以看到它,而不是基于其他 processor/system 开销。由于开销,您不一定会看到 x86 的惩罚,但有时您可以看到一个 arm,进行四个字节大小的传输与一个 32 位传输,甚至两个 16s 与一个 32 位传输。但这取决于,这并不自动意味着你会看到它,这只是意味着你可能会看到。并且了解arm制造内核而不是芯片,因此芯片的大部分与arm无关但整体性能与芯片供应商而非arm有很大关系。
编辑
第二次尝试。
对于写入,cpu 总线通常支持 Fuz 指示的各种大小。 CPU(处理器核心)如今不必处理发生在远端的读取-修改-写入。
对于读取,cpu 总线通常会读取完整的总线宽度,处理器确实需要处理它。但是总线和处理器被设计成一个系统。取决于指令的处理器将提取正确数量的位数,并对它们进行零填充或符号扩展。
这在很大程度上取决于 processor/chip。
我已经看到,根据指令、总线、地址、大小,单个指令 can/may 变成多个总线事务是有道理的。