Getting Physical With Memory

本文探讨了处理器如何通过前端总线(FSB)与内存进行交互,解释了关键引脚的功能,如地址线、数据线及请求引脚,并介绍了FSB事务的不同阶段及其对缓存的影响。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

当我们试图去了解复杂系统时,去除其抽象层,直接关注最底层,我们会更容易去理解。使用这种方法,我们来看一下内存和 I/O 接口的最简单和基础的层:处理器和总线的接口。这些细节是更上层问题的基础,例如线程同步、Core i7 的需求等。然而,由于我是一个程序员,我将忽略一些 EE 人关注的问题。下面展示的是典型的 Core 2 架构:

Core 2 处理器有 775 个引脚,大约一半仅仅提供电力,并不传输数据。当你按功能对这些引脚进行分组时,你会惊奇地发现处理器的物理接口非常简单。图示的是涉及到内存或 I/O 口操作的关键引脚:地址线、数据线以及请求引脚。这些操作都发生在前端总线(Front Side Bus)事务(Transation)上下文中。FSB 事务经历五个阶段:仲裁、请求、侦听、响应以及数据传输。在这些不同的阶段,FSB 上的组件分别扮演了不同的角色,我们称之为代理(agents)。通常这些代理是所有的处理器单元加上北桥。

这篇文章中我们仅仅看一下 请求阶段 —— 由 请求代理 (通常是处理器)发送两个数据包。下面是第一个数据包的数据位,由地址和请求引脚发出:

地址线输出的是事务的起始物理地址,33 位地址引脚线对应的是一个地址的的 3~35 位,地址的 0~2 位为零。因此,对于寻址范围为 64GB 的物理内存,我们得到一个 8 字节对齐的 36 位的地址,这是从 Pentium Pro 处理器之后就这样的。请求引脚表示需要初始化的事务类型,而在 I/O 请求事务中,地址引脚给出的是 I/O 端口而不是内存地址。在第一个数据包输出之后,在接下来的总线时钟周期内又传送了第二个数据包:

属性信号位(Attribute Signals)非常有意思:在 Intel 处理器中,它们代表的了 5 种可用的内存 cache 行为。通过将这个信息传送到 FSB 上,请求代理让其它处理器知道该事务如何影响 cache 的,以及内存控制器(北桥)应该做什么。处理器通过查看页表来决定给定内存区块的类型,页表是由内核来维护的。

通常内核将所有的内存视作写回类型(Write-Back),会获得最好的性能。在写回模式下,内存单元访问的是 cache 行,在 Core 2 中是 64 字节。如果程序读内存的一个字节,处理器加载包含该字节的整个 cache 行到 L2 和 L1 cache 中。当程序写回到内存中,处理器仅仅修改 cahce 行上的数据,而不立刻更新主存。接下来,当它需要将修改的行提交到总线上时,一致性地将整个 cache 行写回。所以,大多请求引脚在 Length 域填写 11,表示请求 64 个字节, 。下面是一个读不在 cache 中的数据的实例:

在 Intel 计算机中将一些物理内存直接映射到硬盘和网卡等设备上,这就允许驱动器通过直接读写内存来与它们的设备通信。内核在页表中将这些内存区域标记为 不可缓存的( uncacheable)。程序或者驱动器请求访问不可缓存的内存区域直接作用在总线上。读写一个字节、一个字等等都是有可能的,这是通过填写上面的数据包 B 的 Byte Enable 字段来完成的。

这里讨论的有很多隐式含义,例如:

  1. 性能敏感的应用应该尝试将数据打包到同一个 cache 行,这样可以一起被访问。一旦 cache 行加载后,接下来的读就避免了从 RAM 中访问,访问速度更快!
  2. 任何对同一 cache 行的内存访问都确保要是原子操作(假设是写回内存模式),这样的一次访问由处理器的 L1 cache 来完成,数据读或写都是一次完成的,不可被其它的处理器或线程来干扰。通常,32 位和 64 位不跨 cahe 行的访存操作都是原子的。
  3. 前端总线由所有的代理共享,在开始一个事务之前需要仲裁总线的所有者。另外,所有的代理为了维护数据的一致性,必须侦听总线上的所有事务。因此,在越来越多的处理器核的添加到 Intel 计算机中,争夺总线资源将成为一个很严重的问题。在 Core i7 处理器中,通过将处理器直接关联到内存上,点对点的通信代替广播来解决这个问题。

这些都是请求物理内存需要关注的重点问题。在接下来将锁、多线程以及内存一致性联系起来之后,总线问题又会浮现出来。我第一次看到 FSB 包描述时,我恍然大悟!我希望你们可有同样的感受。在下一篇文章中,我们爬上抽象层的梯子,看看虚拟内存的全貌。


注:

  • 偶尔看到作者博客,里面的文章我很是喜欢,翻译也只是我来理解作者文章的内容,不建议你们看我翻译,直接看 原文
  • 如果大家发现我哪地方理解有偏差,欢迎指正。
  • 这是一篇关于在处理器体系层次上如何实现访问物理内存的文章,作为一名程序员,我们确实很少关心这个层次的东西,而了解这些对于我们提升自己代码质量有很多帮助。
  • 下一篇我将阅读作者的 Anatomy of a Program in Memory,这是比处理器层次更上一层,讲述一个进程的虚拟内存如何布局的。
### Spring Data JPA Getting Started Guide To begin using Spring Data JPA, it is essential to understand its core concepts and setup process. Below is a comprehensive overview of starting with Spring Data JPA. #### Setting Up Your Project Ensure your project includes the necessary dependencies for Spring Data JPA. This can be achieved by adding the appropriate Maven or Gradle dependency. For example, in Maven: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> ``` This dependency pulls in all required libraries for working with Spring Data JPA[^5]. #### Defining Entity Classes Entity classes represent database tables. These must be annotated with `@Entity` from the Java Persistence API (JPA). Each entity should also define fields corresponding to table columns along with getter and setter methods. Here's an illustrative example: ```java import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; @Entity public class Person { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; private String name; private int age; // Getters and Setters } ``` The above code defines a simple `Person` entity mapped to a relational database table[^3]. #### Creating Repository Interfaces Spring Data JPA simplifies data access through repository interfaces. A typical repository extends either `CrudRepository` or `JpaRepository`. The framework automatically generates implementations based on method signatures defined within these interfaces. Here’s an example of defining a custom repository for the `Person` entity: ```java import org.springframework.data.jpa.repository.JpaRepository; public interface PersonRepository extends JpaRepository<Person, Long> { List<Person> findByName(String name); } ``` In this case, the `findByName` query method will search entities matching the provided name parameter without requiring explicit SQL queries[^3]. Additionally, when creating repositories like `PersonRepository`, ensure they are correctly linked to their respective domain objects as described earlier[^2]. #### Configuring Database Connection Configure the application properties file (`application.properties`) to establish connections between your app and databases such as MySQL, PostgreSQL etc., specifying details including driver class names, URLs, usernames, passwords among others. Example configuration snippet below demonstrates connecting to H2 embedded DB during development phase only: ```properties spring.datasource.url=jdbc:h2:mem:testdb spring.datasource.driverClassName=org.h2.Driver spring.datasource.username=sa spring.datasource.password=password spring.jpa.database-platform=org.hibernate.dialect.H2Dialect ``` With everything configured properly according to official guides mentioned previously [^1], you're now ready to leverage powerful features offered via Spring Data JPA! --- 问题
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值