为什么我的数组索引比指针快 [英] How come my array index is faster than pointer

查看:371
本文介绍了为什么我的数组索引比指针快的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么数组索引比指针快?
是不是指针应该比数组索引快?

**,我用time.h中clock_t表示被测试两种功能,每个回路200万次。

 指针时间:0.018995指数时间:0.017864无效myPointer(int类型的[],INT大小)
{
     INT * P;
     为(P = A; P<&放大器;一【尺寸】; p ++)
     {
         * p值= 0;
     }
}
无效myIndex(int类型的[],INT大小)
{
     INT I;
     对于(i = 0; I<大小;我++)
     {
         一个由[i] = 0;
     }
}


解决方案

没有,从来没有指针应该比数组索引快。如果code中的一个比另一个更快,它主要是由于某些地址计算可能不同。这个问题也应该提供的编译器和优化标志信息,因为它会严重影响性能。

在上下文数组索引(数组边界是不知道)是完全相同的指针操作。从编译器的角度来看,这是指针运算的只是不同的前pression。下面是在Visual Studio 2010中优化的86 code用的全面优化的和的没有内嵌的。

的例子

  3:无效myPointer(int类型的[],INT大小)
     4:{
013E1800推EDI
013E1801 MOV EDI,ECX
     5:INT * P;
     6:(P = A; P<&放大器;一【尺寸】; p ++)
013E1803 LEA ECX,[EDI + EAX * 4]
013E1806 CMP EDI,ECX
013E1808宰myPointer + 15H(13E1815h)
013E180A子ECX,EDI
013E180C月ECX
013E180D SHR ECX,2
013E1810 INC ECX
013E1811 XOR EAX,EAX
013E1813代表STOS DWORD PTR ES:[EDI]
013E1815流行EDI
     7:{
     8:* p值= 0;
     9:}
    10:}
013E1816 RET    13:无效myIndex(int类型的[],INT大小)
    14:{
    15:INT I;
    16:对于(i = 0; I<大小;我++)
013E17F0测试ECX,ECX
013E17F2 JLE myIndex + 0CH(13E17FCh)
013E17F4推EDI
013E17F5 XOR EAX,EAX
013E17F7 MOV EDI,EDX
013E17F9代表STOS DWORD PTR ES:[EDI]
013E17FB流行EDI
    17:{
    18:一个由[i] = 0;
    19:}
    20:}
013E17FC RET

一目了然, myIndex 看起来更快,因为指令数较少,但是,code的两块是基本相同的。双方最终会使用代表STOS ,这是一个86的重复(循环)指令。唯一的区别是,因为约束环的计算。在循环 myIndex 的行程计数尺寸作为它是(即,不需要的计算)。但是, myPointer 需要一些计算来获得的行程计数为循环。这是唯一的区别。重要的循环操作是一样的。因此,不同的是可以忽略不计。

要总结的 myPointer myIndex 以优化code应该是相同的性能。


仅供参考,如果数组的边界在编译时是已知的,例如, INT A [constant_ex pression] ,然后在这个阵列上的访问会快得多比指针之一。这主要是因为该数组访问是从指针分析不出问题。编译器可以完美地计算出依赖信息的计算和访问一个固定大小的数组,所以它可以做先进的优化,包括自动并行化。

然而,如果计算是基于指针,编译器必须进一步优化,这是pretty在C / C多的限制++执行指针分析。它通常与上指针分析保守的结果结束了并导致一些优化机会。

Why the array index is faster than pointer? Isn't pointer supposed to be faster than array index?

** i used time.h clock_t to tested two functions, each loop 2 million times.

Pointer time : 0.018995

Index time : 0.017864

void myPointer(int a[], int size)
{
     int *p;
     for(p = a; p < &a[size]; p++)
     {
         *p = 0;
     }
}


void myIndex(int a[], int size)
{
     int i;
     for(i = 0; i < size; i++)
     {
         a[i] = 0;
     }
}

解决方案

No, never ever pointers are supposed to be faster than array index. If one of the code is faster than the other, it's mostly because some address computations might be different. The question also should provide information of compiler and optimization flags as it can heavily affect the performance.

Array index in your context (array bound is not known) is exactly identical to the pointer operation. From a viewpoint of compilers, it is just different expression of pointer arithmetic. Here is an example of an optimized x86 code in Visual Studio 2010 with full optimization and no inline.

     3: void myPointer(int a[], int size)
     4: {
013E1800  push        edi  
013E1801  mov         edi,ecx  
     5:      int *p;
     6:      for(p = a; p < &a[size]; p++)
013E1803  lea         ecx,[edi+eax*4]  
013E1806  cmp         edi,ecx  
013E1808  jae         myPointer+15h (13E1815h)  
013E180A  sub         ecx,edi  
013E180C  dec         ecx  
013E180D  shr         ecx,2  
013E1810  inc         ecx  
013E1811  xor         eax,eax  
013E1813  rep stos    dword ptr es:[edi]  
013E1815  pop         edi  
     7:      {
     8:          *p = 0;
     9:      }
    10: }
013E1816  ret 

    13: void myIndex(int a[], int size)
    14: {
    15:      int i;
    16:      for(i = 0; i < size; i++)
013E17F0  test        ecx,ecx  
013E17F2  jle         myIndex+0Ch (13E17FCh)  
013E17F4  push        edi  
013E17F5  xor         eax,eax  
013E17F7  mov         edi,edx  
013E17F9  rep stos    dword ptr es:[edi]  
013E17FB  pop         edi  
    17:      {
    18:          a[i] = 0;
    19:      }
    20: }
013E17FC  ret 

At a glance, myIndex looks faster because the number of instructions are less, however, the two pieces of the code are essentially the same. Both eventually use rep stos, which is a x86's repeating (loop) instruction. The only difference is because of the computation of the loop bound. The for loop in myIndex has the trip count size as it is (i.e., no computation is needed). But, myPointer needs some computation to get the trip count of the for loop. This is the only difference. The important loop operations are just the same. Thus, the difference is negligible.

To summarize, the performance of myPointer and myIndex in an optimized code should be identical.


FYI, if the array's bound is known at compile time, e.g., int A[constant_expression], then the accesses on this array may be much faster than the pointer one. This is mostly because the array accesses are free from the pointer analysis problem. Compilers can perfectly compute the dependency information on computations and accesses on a fixed-size array, so it can do advanced optimizations including automatic parallelization.

However, if computations are pointer based, compilers must perform pointer analysis for further optimization, which is pretty much limited in C/C++. It generally ends up with conservative results on pointer analysis and results in a few optimization opportunity.

这篇关于为什么我的数组索引比指针快的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆