最高評価の回答はすべて、実際には決定的な「事実」ではありません...彼らは推測している人々です!
コンパイラによって生成された出力アセンブリを調べて、どのコードがより少ないアセンブリ命令で実行されるかを確認できるため、どのコードの実行に必要なアセンブリ命令が少ないかを明確に知ることができます。
フラグ「gcc-std=c99-S-O3lookingAtAsmOutput.c」を使用してコンパイルしたcコードは次のとおりです。
#include <stdio.h>
#include <stdlib.h>
void swap_traditional(int * restrict a, int * restrict b)
{
int temp = *a;
*a = *b;
*b = temp;
}
void swap_xor(int * restrict a, int * restrict b)
{
*a ^= *b;
*b ^= *a;
*a ^= *b;
}
int main() {
int a = 5;
int b = 6;
swap_traditional(&a,&b);
swap_xor(&a,&b);
}
swap_traditional()のASM出力は>>> 11 <<<命令( "leave"、 "ret"、 "size"を含まない)を取ります:
.globl swap_traditional
.type swap_traditional, @function
swap_traditional:
pushl %ebp
movl %esp, %ebp
movl 8(%ebp), %edx
movl 12(%ebp), %ecx
pushl %ebx
movl (%edx), %ebx
movl (%ecx), %eax
movl %ebx, (%ecx)
movl %eax, (%edx)
popl %ebx
popl %ebp
ret
.size swap_traditional, .-swap_traditional
.p2align 4,,15
swap_xor()のASM出力は>>> 11 <<<「leave」と「ret」を含まない命令を取ります:
.globl swap_xor
.type swap_xor, @function
swap_xor:
pushl %ebp
movl %esp, %ebp
movl 8(%ebp), %ecx
movl 12(%ebp), %edx
movl (%ecx), %eax
xorl (%edx), %eax
movl %eax, (%ecx)
xorl (%edx), %eax
xorl %eax, (%ecx)
movl %eax, (%edx)
popl %ebp
ret
.size swap_xor, .-swap_xor
.p2align 4,,15
アセンブリ出力の要約:
swap_traditional()は11命令を取ります
swap_xor()は11命令を取ります
結論:
どちらの方法も同じ量の命令を使用して実行するため、このハードウェアプラットフォームではほぼ同じ速度です。
教訓:
小さなコードスニペットがある場合、asm出力を確認することは、コードを迅速に反復し、最速の(つまり最小の命令)コードを見つけるのに役立ちます。また、コードを変更するたびにプログラムを実行する必要がないため、時間を節約できます。最後にプロファイラーを使用してコード変更を実行するだけで、コード変更がより高速であることを示すことができます。
私はこの方法を、速度を必要とする重いDSPコードによく使用します。