当前位置: 首页 > 知识库问答 >
问题:

为什么更多的x86指令比更少的快?[副本]

皮煜
2023-03-14

因此,我已经阅读了大约半年的关于x86处理器内部发生的事情。所以我决定尝试一下x86程序集的乐趣,只从80386指令开始,以保持它的简单性。(我主要是在学习,而不是优化)

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

    {
        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)  
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
//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];

共有1个答案

诸嘉澍
2023-03-14

并不是所有的指令都需要相同的时间,现代的CPU实现可以并行执行某些指令的(部分)(只要不读取前一个指令写入的数据,并且所需的单元不冲突)。最新版本确实将“机器”指令转换为更低级别的、非常简单的指令,这些指令被调度为尽可能多地在CPU中的各个单元上并行执行,使用大量的影子寄存器(即,一条指令可以使用%eax的一个副本中的值(旧值),然后另一条指令将一个新值写入%eax的另一个副本(新值),从而进一步解耦指令。为了性能起见,它们跳过的箍...

 类似资料:
  • 我读过,x86的INC指令不是原子指令。我的问题是为什么会这样?假设我们在x86-64上递增一个64位整数,我们可以用一条指令来递增,因为INC指令同时处理内存变量和寄存器。那么为什么它不是原子的呢?

  • 今天我做了一个简单的测试来比较Java和c之间的速度--一个简单的循环,让一个整数“I”从0增加到20亿。 我真的期望C语言比Java更快。我对结果感到惊讶: Java所用的时间(秒):大约。1.8秒 C:大约用秒表示的时间。3.6秒。 我不认为Java是一种更快的语言,但我也不明白为什么在我的简单程序中循环的速度是c的两倍? 我是不是在计划中犯了重大错误?还是MinGW的编译器配置不好还是怎么的

  • 我想知道>是否比>=更快?我试着对其进行基准测试,但要么需要0ms,要么需要永远。我知道差别会很小,但我必须在很多像素上操作。有人能告诉我什么更快吗?

  • 维基百科说A*在O(E)中运行,其中E是图中的边数。但我的朋友说a*只是Dijkstra算法的一般情况,而Dijkstra算法运行在O(E+V log V)中。所以我很困惑为什么A*比Dijkstra的算法跑得更快。

  • 问题内容: 许多Java书籍都将该语句描述为比该语句快。但是我没有找到任何地方为什么切换比if更快。 例 我有一种情况,我必须选择两项中的任何一项。我可以使用 要么 考虑item和BREAD是一个恒定的int值。 在上面的示例中,哪个操作更快,为什么? 问题答案: 因为有很多情况下,有一些特殊的字节码可以有效地评估switch语句。 如果使用IF语句实现,则将进行检查,跳转到下一个子句,进行检查,

  • 问题内容: 阅读此内容后,引人注目: BSON还被设计为快速编码和解码。例如,整数存储为32(或64)位整数,因此不需要在文本之间进行解析。对于小整数,此方​​法比JSON使用更多的空间, 但解析速度要快得多 。 根据我的阅读,使用BSON的全部目的是因为它对CPU的负担更少,并且编码/处理速度更快。 但是,我对Node.js进行了一些测试,并使用本机JSON方法使BSON脱颖而出。一些测试表明J