Page 1 of 1

Small optimization question.

Posted: Thu Jul 08, 2010 8:00 am
by Mincho Georgiev
I am using 2d array of structures
{
uint8 flags;
uint8 delta;
}attack_t;
for attack detection,indexed by [sq][target]. What puzzles me is the intel IA32's translation.
It appears that if I don't use an auxiliary array of pointers, it will be referenced BYTE PTR [_attack_vector+edi+ebp*2],
when the purpose is BYTE PTR [esi+ecx*2]. Every other compiler I tried, including the intel's x64, MSVC 32;64, and so on, made it without ptr array. To be more clearly, here is what I mean in practice.
After reversing the direction in the attack_vector (-dir), I am able to use the reverse indexing [target][sq], since 'sq' is the only dynamically updated value of both.
&attack_t *a = &attack_vector[target][0]; - as a local pointer.
Then 'a[sq].flags, a[sq].delta' is my way to reference the array trough the local pointer. Every other compiler with Od, O2, O3 and so on translate this into BYTE PTR [esi+ecx*2] except intel x86.
The use of auxiliary array of pointers to the attack vector rows, eliminates this issue and the code is equivalent for all compilers.

Code: Select all

//global:
attack_t *atk[128];
//init:
    for(i = 0; i < 128; i++)
        atk[i] = &attack_vector[i][0];
//local
attack_t *a = atk[target];
Any ideas? Thanks.

Re: Small optimization question.

Posted: Thu Jul 08, 2010 1:55 pm
by Gerd Isenberg
In C &attack_vector[0] and attack_vector are equivalent attack_t* expressions. No need to declare and initialize an explicit array of pointers for that, you have that implicit whithout the need of an additional indirection. If "sq" varies more than "target" and is power of two range, it makes indeed sense to use "sq" as least significant index.

What the compiler makes out of this is another question, but you need to post a bit more assembly (and associated C code) to recognice the content of the registers. There are several equivalent x86 addressing modes and expressions to build an effective address, AGU versus ALU.

Gerd

Re: Small optimization question.

Posted: Thu Jul 08, 2010 4:11 pm
by Mincho Georgiev
In C &attack_vector[0] and attack_vector are equivalent attack_t* expressions.
Exactly my point. The difference appears only in listings. During execution, they both are in scaled mode and there is no difference: [edx+eax*2]. The base and the index registers are the same too. I was just wondering, why is listed differently, and why only by intel x86.