https://www.geeksforgeeks.org/write-memcpy/
void myMemCpy(void *dest, void *src, size_t n)
{
// Typecast src and dest addresses to (char *)
char *csrc = (char *)src;
char *cdest = (char *)dest;
// Copy contents of src[] to dest[]
for (int i=0; i<n; i++)
cdest[i] = csrc[i];
}
https://blog.51cto.com/12951882/1978164
都是一個char一個char的復制,不考慮src des重疊的情況的情況,為什么沒有用到uint64_t or uint32_t?
整除64部分用64位,不整除部分用char,復制次數大大減少,速度上不應該有很大提升嗎?
uj5u.com熱心網友回復:
關鍵是記憶體的大小不一定是整數的倍數啊uj5u.com熱心網友回復:
而且現在的編譯器一般都做了優化,不再完全依賴于回圈。uj5u.com熱心網友回復:
從演算法的時間復雜度來講,都是一樣的,都是o(n),n/8和n在演算法的復雜度來講都是一樣的。在實際使用程序中,賦值100次和賦值800次也沒有太大區別
uj5u.com熱心網友回復:
我覺得不能光看表面上回圈次數減少,還要看cpu操作指令差吧,也就是用uint64,每次cpu要使用用8個8位暫存器來操作資料,而使用char每次只需要操作1個8位暫存器,對暫存器的操作次數來說沒什么差別(也就是從記憶體取資料到暫存器,再把暫存器的資料保存到記憶體,8個暫存器要操作8次,即表面上回圈次數減少,實際上cpu操作次數未必少)。而從代碼上來說,用uint64還要自己計算n/sizeof(uint64),即有幾個整的unit64位元組,和n%sizeof(uint64),即有幾個非整的uint64位元組,來分段處理,增加了cpu的操作指令(增加額外操作),所以未必就見得用uint64就能提高效率。uj5u.com熱心網友回復:
有道理,速度的話還是看暫存器。當然,更重要的也是2l的說法。應用場景確實存在非整數倍的時候。
uj5u.com熱心網友回復:
是否需要考慮到位元組序,如果按照樓主的減少回圈次數,但是位元組序如何保證?uj5u.com熱心網友回復:
這個確實會有一定的優化效果的。比如32位的電腦,一次復制4個位元組。64位的電腦一次賦值8個位元組。
都只占用一條CPU指令。
這個需要跟CPU,或者程式的位數有關了。
所以代碼里面實作,會導致移植性變差,C/C++語言的移植性還不錯。
所以這些功能,需要在編譯器級別優化,而不是在代級別優化。
uj5u.com熱心網友回復:
還是有區別的, 總線是分時共用的, 總線帶寬對記憶體移動還是有影響的一次移動多個位元組肯定是比一次一個位元組的效率高的
看匯編命令吧,記憶體之間移動指令: movsb, movsw,movsd
編譯器最后優化成匯編去執行的
uj5u.com熱心網友回復:
都是一個char一個char的復制,不考慮src des重疊的情況的情況,為什么沒有用到uint64_t or uint32_t?整除64部分用64位,不整除部分用char,復制次數大大減少,速度上不應該有很大提升嗎?
==========================
1:我想,myMemCpy是為了演示memcpy的演算法,一個個char的復制,比較能說明問題。
2:如果使用uint64_t or uint32_t ,演算法變得復雜,這樣就失去重點了吧~。需要分成3段寫:copy頭部不對齊部分-->copy對齊部分-->copy尾部不對齊部分。
3:如你所說,優化后復制次數大大減少 ,速度上有極大的提升,庫中的memcpy都有這樣的優化。
4:像memcpy這么基礎的函式,對性能影響極大,通常不會用C寫的,如GCC、MSVC都是用匯撰寫的。
5:一次復制多少位,這和平臺有關的。在例如在x86_64平臺上,glibc、MSVC是按照128位對齊來復制的。
C語言寫的memcpy實用價值不大,主要用來說明記憶體復制演算法,因此在myMemCpy中使用64位優化,意義不是很大。
uj5u.com熱心網友回復:
在真正的RTL實作中,memcpy這種基礎函式實際上有多套實作,針對不同的資料規模和資料對齊情況轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/30917.html
標籤:C語言
