深入理解計算機系統筆記

1.1 嵌套的數組

當我們創建數組的數組時,數組分配和引用的一般原則也是成立的。

例如,聲明 int A[5][3];

等價于下面的聲明

typedef int row3_t[3];

row3_t A[5]

要訪問多維數組的元素,編譯器會以數組起始為基地址, (可能需要經過伸縮的)偏移量為索引,產生計算期望的元素的偏移量,然后使用某種 MOV指令。通常來說,對于一個 聲明如下的數組:

T D[R][C];

它的數組元素D[i][j]的內存地址為

&D[i][j]= Xd?+L(C*i+ j)

這里L是數據類型T以字節為單位的大小。

1.2定長數組

C語言編譯器能夠優化定長多維數組上的操作代碼。這里我們展示優化等級設置為 -01時GCC采用的一些優化。假設我們用如下方式將數據類型fixjnatrix聲明為 16X16 的整型數組:

#define N 16;

typedef int fix_matrix[N][N];

這樣做的好處是,如果需要修改這個值只需要簡單的修改這個# define聲明就可以了。

1.3?變長數組

歷史上,C語言只支持大小在編譯時就能確定的多維數組(對第一維可能有些例外)。 程序員需要變長數組時不得不用malloc或calloc這樣的函數為這些數組分配存儲空間,而且不得不顯式地編碼,用行優先索引將多維數組映射到一維數組,ISO C99引入了一種功能,允許數組的維度是表達式,在數組被分配的時候才計算出來。

在變長數組的C版本中,我們可以將一個數組聲明如下:

int? A[expr1]?[expr2];

它可以作為一個局部變量,也可以作為一個函數的參數,然后在遇到這個聲明的時候,通過對表達式和求值來確定數組的維度。

因此,例如要訪問 n *n 數組的元素 I ,j,我們可以寫一個如下的函數:

int var_ele(long n, int A[n][n], long i, long j){

return A[i][j]; }

參數n必須在參數A[n][n]之前,這樣函數就可以在遇到這個數組的時候計算出數組的維度。

GCC為這個引用函數產生的代碼如下所示:

int var_ele(long n, int A[n][n], long i, long j)

n in %rdi,?A in %rsi,?i in %rdx, j in %rcx

1??var_ele:

2? imulq %rdx, %rdi

3??leaq (%rsi,%rdi*4), %rax

4??movl?(%rax,%rcx,4), %eax

5??ret

這 個地址的計算類似于定長數組的地址計算,不同點在于

1)由于增加了參數 n, 寄存器的使用變化了;

2)用了乘法指令來計算n?* i(第2行),而不是用leaq指令來計算3i?。因此引用變長數組只需要對定長數組做一點兒概括。

動態的版本必須用乘法指令對 i 伸縮n倍,而不能用一系列的移位和加法。在一些處理器中,乘法會招致嚴重的性能處 罰,但是在這種情況中無可避免。

2.1異質的數據結構

C語言提供了兩種將不同類型的對象組合到一起創建數據類型的機制:結構(structure),用關鍵字 struct 來聲明,將多個對象集合到一個單位中;聯合(union),用關鍵 字union 來聲明,允許用幾種不同的類型來引用一個對象

2.2結構

C語言的struct聲明創建一個數據類型,將可能不同類型的對象聚合到一個對象中。 用名字來引用結構的各個組成部分。類似于數組的實現,結構的所有組成部分都存放在內存中一段連續的區域內,而指向結構的指針就是結構第一個字節的地址。編譯器維護關于每個結構類型的信息,指示每個字段(field)的字節偏移。它以這些偏移作為內存引用指令中的位移,從而產生對結構元素的引用。

2.3聯合

聯合提供了一種方式,能夠規避C語言的類型系統,允許以多種類型來引用一個對 象。聯合聲明的語法與結構的語法一樣,只不過語義相差比較大。它們是用不同的字段來引用相同的內存塊。

考慮下面的聲明: struct S3{

char c;

int i[2];

double v;

};

union U3{

char c;

int i[2];

double v;?

};

在一臺x86-64Lmux機器上編譯時,字段的偏移量、數據類型S3和U3的完整大小如下:

在一些下上文中,聯合十分有用。但是,它也能引起一些討厭的錯誤,因為它們繞過 了C語言類型系統提供的安全措施。一種應用情況是,我們事先知道對一個數據結構中的兩個不同字段的使用是互斥的,那么將這兩個字段聲明為聯合的一部分,而不是結構的一 部分,會減小分配空間的總量。

2.4數據對齊

許多計算機系統對基本數據類型的合法地址做出了一些限制,要求某種類型對象的地 址必須是某個值K(通常是2、4或8)的倍數。這種對齊限制簡化了形成處理器和內存系統 之間接口的硬件設計。

例如,假設一個處理器總是從內存中取8個字節,則地址必須為8 的倍數。如果我們能保證將所有的double類型數據的地址對齊成8的倍數,那么就可以 用一個內存操作來讀或者寫值了。否則,我們可能需要執行兩次內存訪問,因為對象可能被分放在兩個8字節內存塊中。

對齊原則是任何K字節的基本對象的地址必須是K?的倍數。可以 看到這條原則會得到如下對齊:

確保每種數據類型都是按照指定方式來組織和分配,即每種類型的對象都滿足它的對齊限制,就可保證實施對齊。編譯器在匯編代碼中放人命令,指明全局數據所需的對齊。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/711752.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/711752.shtml
英文地址,請注明出處:http://en.pswp.cn/news/711752.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【Ai生態開發】Spring AI上架,打造專屬業務大模型,AI開發再也不是難事!

大家好 這里是蘇澤 后端是工作 ai是興趣 對于ai的產生我的立場是擁抱ai的 是希望拿他作為提升能力的工具 那么這一篇帶大家來學習如何使用ai打造一個專屬的業務大模型 需求 就是說假設現在有一個 商城系統 里面有查詢訂單的api和獲取商品購買方式的api 用戶只需要輸入 “…

C++二叉搜樹的實現(遞歸和非遞歸)

目錄 1.什么是二叉搜索樹 2.二叉搜索樹的查找 3.二叉搜索樹插入 4.二叉搜索樹的刪除 1.刪除的節點只有左子樹或者右子樹 2.刪除節點左右子樹都有的情況 5.代碼 1.什么是二叉搜索樹 左節點的值小于根節點 右節點大于根節點 左右子樹也滿足上面兩個條件 例:…

平臺工程與安全

平臺工程不是為了取代DevOps,而是DevOps的進一步演進和發展。本文介紹了DevOps和平臺工程,以及對于安全的意義。原文: Platform Engineering and Security: A Very Short Introduction 中國云南大理的日落 我是一名 DevOps 工程師,個人還是希…

c# 調用存儲過程

1.調用返回OUT的存儲過程 a.調用OUT字符串的存儲過程&#xff1b; #region 連接數據庫/// <summary>/// 連接數據庫/// </summary>/// <param name"connStatus"></param>/// <param name"dbNode"></param>/// <ret…

Android WebView訪問網頁+自動播放視頻+自動全屏+切換橫屏

一、引言 近期&#xff0c;我發現電視家、火星直播等在線看電視直播的軟件都已倒閉&#xff0c;而我奶奶也再無法通過這些平臺看電視了。她已六十多歲&#xff0c;快七十歲啦。這些平臺的倒下對我來說其實沒有多大的影響&#xff0c;但是對于文化不多的她而言&#xff0c;生活中…

Linux下的時間同步,以及ntp時間服務器配置流程

Linux下的時間同步&#xff0c;以及ntp時間服務器配置流程 概論常見時間操作命令Linux下的系統時間配置Linux硬件的時間的設置系統時間和硬件時間的同步NTP服務器時間的同步NTP服務的安裝NTP的時間同步定時任務里的時間同步配置文件同步時間 概論 但在Linux下&#xff0c;系統…

SpringBoot中間件簡介

Spring Boot是一個Java框架&#xff0c;它提供了一系列中間件來簡化應用程序的開發和集成。以下是一些常見的Spring Boot中間件&#xff1a; Web中間件&#xff1a; Servlet容器&#xff08;內嵌Tomcat、Jetty或Undertow&#xff09; Spring MVC&#xff08;用于構建Web應用程…

HBuilderX創建uniapp項目使用 tailwindcss

文章目錄 一、創建package.json文件二、打開終端 yarn / npm 安裝依賴三、創建 vue.config.js文件四、創建postcss.config.js文件五、創建tailwind.config.js文件六、App.vue文件的style中引入tailwindcss 一、創建package.json文件 {"devDependencies": {"aut…

藍橋杯算法 一.

分析&#xff1a; 本題記錄&#xff1a;m個數&#xff0c;異或運算和為0&#xff0c;則相加為偶數&#xff0c;后手獲勝。 分析&#xff1a; 369*99<36500&#xff0c;369*100>36500。 注意&#xff1a;前綴和和后綴和問題

知識(202402)

1.Conditional Conditional來源于spring-context包下的一個注解。Conditional中文是條件的意思&#xff0c;Conditional注解它的作用是按照一定的條件進行判斷&#xff0c;滿足條件給容器注冊bean。 可以控制一個配置類是否注入到容器中&#xff0c;比如控制xxl-job不自動注冊…

【wpf】關于綁定的一點明悟

背景簡介 軟件功能為&#xff0c;讀取一個文件夾下的所有子文件夾&#xff0c;每個文件夾對自動對應生成 一組 “按鍵四個勾選” 按鍵點擊觸發&#xff0c;可以發送與其對應文件夾中的一些內容。這個綁定的過程我在之前的文章有過詳細的介紹&#xff0c;非常的簡單。 這里回顧…

3月1日做題總結(靜態庫與動態庫)

前言 最近學到了靜態庫和動態庫的相關知識&#xff0c;就順便整理了一下相關題目。如果對靜態庫和動態庫知識不熟悉的同學&#xff0c;推薦看這篇文章——《靜態庫與動態庫》&#xff0c;講的很詳細。 第一題 關于靜態庫與動態庫的區別&#xff0c;以下說法錯誤的是&#xff…

mac jupyter使用現有的python環境

mood&#xff1a;python 編程真的是在反復的與自己和解啊 本來超級的畏難情緒 讀會兒書 計算機博士的書 感覺還是要堅強的。《研磨記》--一位博士生的回憶錄 作者技術真的強啊 正文開始&#xff1a; 聚焦搜索&#xff0c;打開終端激活虛擬環境&#xff1a;conda activate pyt…

力扣爆刷第83天之hot100五連刷1-5

力扣爆刷第83天之hot100五連刷1-5 文章目錄 力扣爆刷第83天之hot100五連刷1-5一、1. 兩數之和二、49. 字母異位詞分組三、128. 最長連續序列四、283. 移動零五、11. 盛最多水的容器 一、1. 兩數之和 題目鏈接&#xff1a;https://leetcode.cn/problems/two-sum/description/?…

javascript中使用‘use strict’和不使用的區別

錯誤處理&#xff1a; 嚴格模式使得 JavaScript 對某些可能的問題拋出錯誤&#xff0c;而在非嚴格模式下&#xff0c;這些問題可能會被忽略。例如&#xff0c;未聲明的變量&#xff08;即全局變量&#xff09;在非嚴格模式下會被隱式地創建為全局變量&#xff0c;而在嚴格模式…

十一、 二進制位運算

描述 Python有位運算&#xff0c;是直接將數字看成二進制&#xff0c;直接對二進制數字的每一位進行運算。現輸入兩個十進制整數x、y&#xff0c;請計算它們的位與、位或&#xff0c;輸出按照十進制的形式。 輸入描述&#xff1a; 一行輸入兩個整數x、y&#xff0c;以空格間…

git:合并兩個不同倉庫的代碼

有兩個代碼倉庫&#xff1a;代碼倉庫A、代碼倉庫B&#xff0c;其中一個倉庫的代碼是為了新項目拉取的新分支&#xff0c;所以分支的部分修改歷史是相同的 現在要將代碼倉庫B 的代碼合并到代碼倉庫A 實現思路&#xff1a;分支合并 實現步驟&#xff1a; # 1、clone代碼倉庫A…

外匯天眼:ASIC 獲得針對前 Blockchain Global 董事的臨時出行限制令

澳大利亞證券與投資委員會&#xff08;ASIC&#xff09;已經針對前Blockchain Global Limited&#xff08;清算中&#xff09;董事梁國&#xff08;又名Allan Guo&#xff09;獲得了臨時旅行限制令。這些命令在其他方面&#xff0c;阻止郭先生在2024年8月20日或進一步命令之前離…

(done) 如何計算 Hessian Matrix 海森矩陣 海塞矩陣

參考視頻1&#xff1a;https://www.bilibili.com/video/BV1H64y1T7zQ/?spm_id_from333.337.search-card.all.click 參考視頻2&#xff08;正定矩陣&#xff09;&#xff1a;https://www.bilibili.com/video/BV1Ag411M76G/?spm_id_from333.337.search-card.all.click&vd_…

【JGit】 AddCommand 新增的文件不能添加到暫存區

執行git.add().addFilepattern(".").setUpdate(true).call() 。新增的文件不能添加到暫存區&#xff0c;為什么&#xff1f; 在 JGit 中&#xff0c;setUpdate(true) 方法用于在調用 AddCommand 的 addFilepattern() 方法時&#xff0c;將已跟蹤文件標記為需要更新。…