一篇文章帶你了解C語(yǔ)言?xún)?nèi)存對(duì)齊解決的問(wèn)題
一、內(nèi)存對(duì)齊為4個(gè)字節(jié)的好處
首先,了解一下CPU從內(nèi)存里讀取數(shù)據(jù)的流程:
第一步,CPU通過(guò)地址總線(xiàn),找到該數(shù)據(jù)的位置。
第二步,通過(guò)控制總線(xiàn),發(fā)送讀取數(shù)據(jù)的指令。
第三步,通過(guò)數(shù)據(jù)總線(xiàn),從內(nèi)存里獲取該數(shù)據(jù)的內(nèi)容。
內(nèi)存對(duì)齊使用4個(gè)字節(jié)的原因有:
1.STM32單片機(jī)的數(shù)據(jù)總線(xiàn)與地址總線(xiàn)都是32bit(4個(gè)字節(jié))。
2.方便DMA的搬運(yùn),DMA搬運(yùn)的最大內(nèi)存是32bit(4個(gè)字節(jié))。
二、內(nèi)存對(duì)齊的目的是以空間換取速度
2.1、內(nèi)存對(duì)齊為4的例子
/* 先來(lái)一個(gè)簡(jiǎn)單的結(jié)構(gòu)體 */ struct { char a; int b; }Test2;
CPU讀取內(nèi)存里數(shù)據(jù)的過(guò)程:
1.想找變量a:第一次讀取就能找到。
2.想找變量b:第二次讀取就能找到。
這一點(diǎn)很重要,變量a與變量b各自只需要1次尋址就能完成讀取。接下來(lái)看一看內(nèi)存如果沒(méi)有使用內(nèi)存對(duì)齊的例子(當(dāng)我不知道內(nèi)存對(duì)齊時(shí),我也是誤以為內(nèi)存里的數(shù)據(jù)是這樣分布的?。?/p>
2.2、內(nèi)存沒(méi)有使用內(nèi)存對(duì)齊的例子
如果內(nèi)存沒(méi)有使用內(nèi)存對(duì)齊的話(huà),構(gòu)想的內(nèi)存分布如下:
CPU讀取數(shù)據(jù)的過(guò)程:
1.想找變量a:第一次讀取就能找到。
2.想找變量b:先讀取第一組內(nèi)存的后三個(gè)字節(jié),接著再讀取第二組內(nèi)存的第一個(gè)字節(jié),最后將所有字節(jié)合并為4個(gè)字節(jié)。
如果內(nèi)存沒(méi)有使用內(nèi)存對(duì)齊的話(huà),CPU為了獲取變量b花掉了兩次地址尋址,接著還要將字節(jié)合并。所以,內(nèi)存對(duì)齊可以有效地提高CPU讀寫(xiě)內(nèi)存的速度,但是浪費(fèi)一點(diǎn)空間。
三、掌握內(nèi)存對(duì)齊的必要性
了解內(nèi)存對(duì)齊的作用后,就能弄懂為什么編譯器要對(duì)某些內(nèi)存做了填充。比如本章節(jié)的例子,如果結(jié)構(gòu)體里只有一個(gè)char與int變量,無(wú)論是char變量在前,還是int變量在前,都肯定會(huì)浪費(fèi)3個(gè)字節(jié)被用于填充,湊夠4個(gè)字節(jié)變成一組數(shù)據(jù)被CPU一次性讀取。
總結(jié)
本篇文章就到這里了,希望能給你帶來(lái)幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
- C語(yǔ)言結(jié)構(gòu)體內(nèi)存對(duì)齊詳解
- C語(yǔ)言熱門(mén)考點(diǎn)結(jié)構(gòu)體與內(nèi)存對(duì)齊詳解
- C語(yǔ)言中結(jié)構(gòu)體與內(nèi)存對(duì)齊實(shí)例解析
- C語(yǔ)言中結(jié)構(gòu)體、聯(lián)合體的成員內(nèi)存對(duì)齊情況
- 一篇文章帶你了解C語(yǔ)言?xún)?nèi)存對(duì)齊公式
- 一篇文章帶你了解C語(yǔ)言?xún)?nèi)存對(duì)齊
- C語(yǔ)言重難點(diǎn)之內(nèi)存對(duì)齊和位段
- C語(yǔ)言?xún)?nèi)存對(duì)齊實(shí)例詳解
- 深入理解C語(yǔ)言?xún)?nèi)存對(duì)齊
- C語(yǔ)言結(jié)構(gòu)體中內(nèi)存對(duì)齊的問(wèn)題理解
相關(guān)文章
基于Qt實(shí)現(xiàn)一個(gè)圖片對(duì)比選擇瀏覽器
這篇文章主要為大家詳細(xì)介紹了如何基于Qt實(shí)現(xiàn)一個(gè)圖片對(duì)比選擇瀏覽器,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2024-04-04C語(yǔ)言實(shí)現(xiàn)套接字操作的示例代碼
在C語(yǔ)言中,套接字(Socket)是一種進(jìn)行網(wǎng)絡(luò)通信的接口,這篇文章就來(lái)和大家介紹一下C語(yǔ)言中是如何進(jìn)行套接字操作的,需要的可以參考一下2023-06-06C++?move()函數(shù)及priority_queue隊(duì)列使用記錄
move(obj)函數(shù)的功能是把obj當(dāng)做右值處理,可以應(yīng)用在對(duì)象的移動(dòng)上,這篇文章主要介紹了C++?move()函數(shù)及priority_queue隊(duì)列使用記錄,需要的朋友可以參考下2023-01-01錯(cuò)誤:sem_union的存儲(chǔ)大小未知問(wèn)題的解決方法
這篇文章主要介紹了錯(cuò)誤:sem_union的存儲(chǔ)大小未知問(wèn)題的解決方法,需要的朋友可以參考下2016-10-10為什么要學(xué)習(xí)C語(yǔ)言 C語(yǔ)言?xún)?yōu)勢(shì)分析
不止一個(gè)學(xué)生問(wèn)到我:“老師,為什么我們的應(yīng)用程序設(shè)計(jì)要學(xué)C語(yǔ)言而不是別的?C語(yǔ)言不是已經(jīng)過(guò)時(shí)了嗎?如果現(xiàn)在要寫(xiě)一個(gè)Windows程序,用VB或Dephi開(kāi)發(fā)多快呀,用C行嗎?退一萬(wàn)步,為什么選擇C而不是C++呢?”2013-07-07C++ RTTI與4種類(lèi)型轉(zhuǎn)換的深入理解
這篇文章主要給大家介紹了關(guān)于C++ RTTI與4種類(lèi)型轉(zhuǎn)換的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-03-03C/C++?Qt?數(shù)據(jù)庫(kù)QSql增刪改查組件應(yīng)用教程
Qt?SQL模塊是Qt中用來(lái)操作數(shù)據(jù)庫(kù)的類(lèi),該類(lèi)封裝了各種SQL數(shù)據(jù)庫(kù)接口,可以很方便的鏈接并使用。本文主要介紹了Qt數(shù)據(jù)庫(kù)QSql增刪改查組件的應(yīng)用教程,感興趣的同學(xué)可以學(xué)習(xí)一下2021-12-12