gpt4 book ai didi

c - 为什么更多的 x86 指令比更少的更快?

转载 作者:行者123 更新时间:2023-12-04 17:12:05 26 4
gpt4 key购买 nike

所以我已经阅读有关 x86 处理器内部发生的事情大约半年了。所以我决定尝试一下 x86 汇编,为了好玩,只从 80386 指令开始,以保​​持简单。 (我主要是在努力学习,而不是优化)

我有一个几个月前用 C 编写的游戏,所以我去了那里,用汇编代码从头开始重写了位图 blitting 函数。我没有得到的是循环的主要像素绘图体使用 C 代码(18 条指令)比我的汇编代码(只有 7 条指令,我几乎 100% 肯定它没有)更快t 跨越缓存行边界)。

所以我的主要问题是为什么 18 条指令比 7 条指令花费的时间少?在底部我有 2 个代码片段。

附言。每种颜色都是 8 位索引。C代码:

    {
for (x = 0; x < src.w; x++)
00D35712 mov dword ptr [x],0 // Just initial loop setup
00D35719 jmp Renderer_DrawBitmap+174h (0D35724h) // Just initial loop setup
00D3571B mov eax,dword ptr [x]
00D3571E add eax,1
00D35721 mov dword ptr [x],eax
00D35724 mov eax,dword ptr [x]
00D35727 cmp eax,dword ptr [ebp-28h]
00D3572A jge Renderer_DrawBitmap+1BCh (0D3576Ch)
{
*dest_pixel = renderer_trans[renderer_light[*src_pixel][light]][*dest_pixel][trans];
// Start of what I consider the body
00D3572C mov eax,dword ptr [src_pixel]
00D3572F movzx ecx,byte ptr [eax]
00D35732 mov edx,dword ptr [light]
00D35735 movzx eax,byte ptr renderer_light (0EDA650h)[edx+ecx*8]
00D3573D shl eax,0Bh
00D35740 mov ecx,dword ptr [dest_pixel]
00D35743 movzx edx,byte ptr [ecx]
00D35746 lea eax,renderer_trans (0E5A650h)[eax+edx*8]
00D3574D mov ecx,dword ptr [dest_pixel]
00D35750 mov edx,dword ptr [trans]
00D35753 mov al,byte ptr [eax+edx]
00D35756 mov byte ptr [ecx],al
dest_pixel++;
00D35758 mov eax,dword ptr [dest_pixel]
00D3575B add eax,1
00D3575E mov dword ptr [dest_pixel],eax
src_pixel++;
00D35761 mov eax,dword ptr [src_pixel]
00D35764 add eax,1
00D35767 mov dword ptr [src_pixel],eax
// End of what I consider the body
}
00D3576A jmp Renderer_DrawBitmap+16Bh (0D3571Bh)

还有我写的汇编代码:(esi是源像素,edi是屏幕缓冲区,edx是亮度级别,ebx是透明度级别,ecx是这一行的宽度)

drawing_loop:
00C55682 movzx ax,byte ptr [esi]
00C55686 mov ah,byte ptr renderer_light (0DFA650h)[edx+eax*8]
00C5568D mov al,byte ptr [edi]
00C5568F mov al,byte ptr renderer_trans (0D7A650h)[ebx+eax*8]
00C55696 mov byte ptr [edi],al

00C55698 inc esi
00C55699 inc edi
00C5569A loop drawing_loop (0C55682h)
// This isn't just the body this is the full row plotting loop just like the code above there

对于上下文,像素是用 LUT 照亮的,透明度也是用 LUT 完成的。伪C代码:

//transparencyLUT[new][old][transparency level (0 = opaque, 7 = full transparency)]
//lightLUT[color][light level (0 = white, 3 = no change, 7 = full black)]
dest_pixel = transparencyLUT[lightLUT[source_pixel][light]]
[screen_pixel]
[transparency];

让我着迷的是我如何使用与 C 代码几乎相同的指令,但使用的指令更少?

如果您需要更多信息,我很乐意提供更多信息,我只是不希望这是一个大问题。我真的很好奇,因为我对 x86 汇编编程有点陌生,想了解更多关于我们的 cpus 实际工作方式的信息。

我唯一的猜测是乱序执行引擎不喜欢我的代码,因为它的所有内存访问都移动到同一个寄存器。

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com