問題描述
讓我們考慮一個對象 foo
(可能是一個 int
、一個 double
、一個自定義的 struct
,一個 class
,隨便).我的理解是通過引用一個函數來傳遞 foo
(或者只是傳遞一個指向 foo
的指針)會導致更高的性能,因為我們避免制作本地副本(這可能很昂貴)如果 foo
很大).
Let's consider an object foo
(which may be an int
, a double
, a custom struct
, a class
, whatever). My understanding is that passing foo
by reference to a function (or just passing a pointer to foo
) leads to higher performance since we avoid making a local copy (which could be expensive if foo
is large).
然而,從答案 here 看來,64 位系統上的指針實際上可以預期為 8 字節大小,而不管指向的是什么.在我的系統上,一個 float
是 4 個字節.這是否意味著如果 foo
是 float
類型,那么按值傳遞 foo
會更有效而不是給出一個指向它的指針(假設沒有其他約束會使得在函數內使用一個比另一個更有效)?
However, from the answer here it seems that pointers on a 64-bit system can be expected in practice to have a size of 8 bytes, regardless of what's being pointed. On my system, a float
is 4 bytes. Does that mean that if foo
is of type float
, then it is more efficient to just pass foo
by value rather than give a pointer to it (assuming no other constraints that would make using one more efficient than the other inside the function)?
推薦答案
這取決于您所說的成本"是什么意思,以及與操作相關的主機系統(硬件、操作系統)的屬性.
It depends on what you mean by "cost", and properties of the host system (hardware, operating system) with respect to operations.
如果您的成本度量是內存使用,那么成本的計算是顯而易見的 - 將復制的大小相加.
If your cost measure is memory usage, then the calculation of cost is obvious - add up the sizes of whatever is being copied.
如果您衡量的是執行速度(或效率"),那么游戲就不同了.借助專用電路(機器寄存器及其使用方式),硬件(以及操作系統和編譯器)往往會針對復制特定大小的事物的操作性能進行優化.
If your measure is execution speed (or "efficiency") then the game is different. Hardware (and operating systems and compiler) tend to be optimised for performance of operations on copying things of particular sizes, by virtue of dedicated circuits (machine registers, and how they are used).
例如,機器具有導致最佳位置"的架構(機器寄存器、內存架構等)是很常見的 - 復制某種大小的變量最有效",但復制更大的 ORSMALLER 變量則不然.較大的變量復制成本更高,因為可能需要對較小的塊進行多次復制.較小的也可能花費更多,因為編譯器需要將較小的值復制到較大的變量(或寄存器)中,對其進行操作,然后再將值復制回來.
It is common, for example, for a machine to have an architecture (machine registers, memory architecture, etc) which result in a "sweet spot" - copying variables of some size is most "efficient", but copying larger OR SMALLER variables is less so. Larger variables will cost more to copy, because there may be a need to do multiple copies of smaller chunks. Smaller ones may also cost more, because the compiler needs to copy the smaller value into a larger variable (or register), do the operations on it, then copy the value back.
浮點示例包括一些 cray 超級計算機,它們本機支持雙精度浮點(在 C++ 中又稱為 double
),以及所有單精度運算(在 C++ 中也稱為 float
)C++) 在軟件中被模擬.一些較舊的 32 位 x86 CPU 也在內部使用 32 位整數,并且由于與 32 位之間的轉換,對 16 位整數的操作需要更多的時鐘周期(這對于更現代的 32 位或 64-位 x86 處理器,因為它們允許將 16 位整數復制到 32 位寄存器或從 32 位寄存器復制并對其進行操作,這樣的懲罰較少).
Examples with floating point include some cray supercomputers, which natively support double precision floating point (aka double
in C++), and all operations on single precision (aka float
in C++) are emulated in software. Some older 32-bit x86 CPUs also worked internally with 32-bit integers, and operations on 16-bit integers required more clock cycles due to translation to/from 32-bit (this is not true with more modern 32-bit or 64-bit x86 processors, as they allow copying 16-bit integers to/from 32-bit registers, and operating on them, with fewer such penalties).
按值復制一個非常大的結構比創建和復制它的地址效率低,這有點顯而易見.但是,由于上述因素,最好按值復制這種大小的東西"和最好傳遞其地址"之間的交叉點不太清楚.
It is a bit of a no-brainer that copying a very large structure by value will be less efficient than creating and copying its address. But, because of factors like the above, the cross-over point between "best to copy something of that size by value" and "best to pass its address" is less clear.
指針和引用往往以類似的方式實現(例如,按引用傳遞可以以與傳遞指針相同的方式實現),但這并不能保證.
Pointers and references tend to be implemented in a similar manner (e.g. pass by reference can be implemented in the same way as passing a pointer) but that is not guaranteed.
唯一確定的方法是測量它.并意識到測量值會因系統而異.
The only way to be sure is to measure it. And realise that the measurements will vary between systems.
這篇關于按值傳遞與按引用或按指針傳遞的性能成本?的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!