簡體   English   中英

使用寄存器交換值

[英]Swapping values using registers

我一直在閱讀有關不使用臨時變量而交換變量內容的信息,除了著名的xor算法之外,我還從x86上的匯編中發現了有關XCHG指令的信息。 所以我寫了這段代碼:

void swap(int *left, int *right){
__asm__ __volatile__(
        "movl %0, %%eax;"
        "movl %1, %%ebx;"
        :
        : "r" (*left), "r" (*right)
    );
__asm__ __volatile__(
        "xchg %eax, %ebx;"
            );
__asm__ __volatile__(
        "movl %%eax, %0;"
        "movl %%ebx, %1;"
        : "=r" (*left), "=r" (*right)
    );}

它確實起作用,但是后來我意識到根本不需要XCHG指令。

void swap(int *left, int *right){
__asm__ __volatile__(
        "movl %0, %%eax;"
        "movl %1, %%ebx;"
        :
        : "r" (*left), "r" (*right)
    );
__asm__ __volatile__(
        "movl %%ebx, %0;"
        "movl %%eax, %1;"
        : "=r" (*left), "=r" (*right)
    );}

第二個函數也起作用,但是似乎沒有人提到使用寄存器交換變量,因此此代碼是否被認為是錯誤的,實際上它並不能正常工作? 我想念什么嗎?

我意識到這僅適用於x86,但是由於大多數人都擁有Intel x86處理器,該代碼可以在任何現實世界的編程中使用嗎? 我意識到這可能不會比使用臨時變量進行常規交換快得多,但我是從理論上提出問題的。 如果在測試或面試中有人要求我用C編寫一個函數以交換x86機器的值而不使用臨時變量,那么此代碼是否有效或完全是廢話? 謝謝。

有效,是的。 根據我的標准,您是免費的。

為什么? 成本。

std :: swap可以很好地完成工作,並且可能足夠快。 您的代碼將具有較高的維護成本。

出於性能原因,肯定有很多時候需要使用匯編程序。
這不是其中的一個。

首先,內聯程序集在很多方面都被破壞了:

  • 濫用volatile ,並不意味着您想要什么。
  • 您不會告訴編譯器您破壞了寄存器。 (可以解決)
  • 編譯器可以自由地在內聯匯編塊之間插入代碼

對於程序員和編譯器而言,內聯匯編都很難正確實現。

另外,內聯匯編可能會經過非常謹慎的修改后進行優化,但是它會以影響優化器功能(寄存器分配,重新排序等)的方式影響編譯器,這通常會導致整體性能下降。 我不反對內聯匯編(或編譯器內部函數),但是它需要非常謹慎的處理,這在大多數情況下都不合理。

std::swap將比此編譯為更有效的asm。

該代碼比編譯器發出的代碼慢,而且損壞。

它會在不通知編譯器的情況下掩蓋EAX和EBX,尤其是在啟用優化的情況下進行編譯時,它很容易失敗,但即使沒有優化也不安全。

請參閱如何編寫簡短的內聯gnu擴展程序集塊以交換兩個整數變量的值? 例如,一個關於xchg的正確 asm的示例,以及一個更好的版本,它僅使用約束條件以零個asm指令交換C變量,而讓編譯器找出它想要在哪個寄存器中使用哪個C變量asm("" : "=r" (a), "=r" (b) : "1" (a), "0" (b));


即使您使用具有0條asm語句和正好相反的輸入/輸出約束的內聯asm進行了此操作,您仍然會破壞常量傳播和范圍分析,從而使優化失敗。 https://gcc.gnu.org/wiki/DontUseInlineAsm 之前鏈接的答案的編輯內容包括一個純C交換,它表明常量傳播在那里起作用,但與inline-asm交換都不起作用。

因此,即使正確編寫的這個版本仍然是無用的任何真實世界的用途,但在使用輸入/輸出約束GNU C內聯匯編,以避免運動/例如其他mov在實ASM塊的開始/結束,並盡可能多地交給編譯器。


如果您做某事,編譯器無法比您個人做得更好,那么Asm只能贏得性能。 用於測試Collat​​z猜想的C ++代碼比手寫匯編要快-為什么?

查看正常功能的編譯器的asm輸出( 如何從GCC / clang程序集輸出中消除“噪聲”? ),然后查看

進一步了解有效組裝的要素。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM