Продолжение флейма к Areex
От: Awaken Украина  
Дата: 14.04.03 13:09
Оценка:
итак указатели vs индексы.
вот написал я более нетривиальный пример — реверс строки


void mystrrev(char *source, int len)
{
   char t=0, *p=NULL, *e=NULL;
   for(p = source, e = p + len; p < e; )
   {
      t = *p;
      *p++ = *e;
      *e-- = t;
   }

}


асмовский выход для первой функции

   mov         ebp,esp
   add         byte ptr [eax],al
   mov         ecx,dword ptr [ebp+8]
   mov         eax,dword ptr [ebp+0Ch]
   add         eax,ecx
   cmp         ecx,eax
   jae         exit
   push        ebx
loop:
   mov         bl,byte ptr [eax]
   mov         dl,byte ptr [ecx]
   mov         byte ptr [ecx],bl
   inc         ecx
   mov         byte ptr [eax],dl
   dec         eax
   cmp         ecx,eax
   jb          loop
   pop         ebx
exit:
   pop         ebp
   ret



теперь тот же код без применения указателей

void mystrrev1(char *source, int len)
{
   char t=0, p=0, e=0;
   for(p = 0, e = len; p < e; )
   {
      t = source[p];
      source[p++] = source[e];
      source[e--] = t;
   }

}



асмовский выход (optimize speed)

   push        ebp
   mov         ebp,esp
   mov         cl,byte ptr [ebp+0Ch]
   xor         al,al
   test        cl,cl
   jle         exit
   push        ebx
   push        esi
   push        edi
loop:
   mov         edi,dword ptr [ebp+8]
   movsx       edx,al
   movsx       ebx,cl
   lea         esi,[edx+edi]
   mov         dl,byte ptr [esi]
   add         edi,ebx
   mov         bl,byte ptr [edi]
   inc         al
   dec         cl
   cmp         al,cl
   mov         byte ptr [esi],bl
   mov         byte ptr [edi],dl
   jl          loop
   pop         edi
   pop         esi
   pop         ebx
exit:
   pop         ebp
   ret


асмовский выход (optimize size):

   push        ebp
   mov         ebp,esp
   push        ecx
   mov         al,byte ptr [ebp+0Ch]
   and         byte ptr [ebp-1],0
   test        al,al
   mov         byte ptr [ebp+0Fh],al
   jle         exit
   push        ebx
   push        esi
   mov         esi,dword ptr [ebp+8]
loop:
   movsx       ecx,byte ptr [ebp+0Fh]
   movsx       eax,byte ptr [ebp-1]
   mov         dl,byte ptr [eax+esi]
   mov         bl,byte ptr [ecx+esi]
   add         eax,esi
   add         ecx,esi
   inc         byte ptr [ebp-1]
   dec         byte ptr [ebp+0Fh]
   mov         byte ptr [eax],bl
   mov         al,byte ptr [ebp-1]
   cmp         al,byte ptr [ebp+0Fh]
   mov         byte ptr [ecx],dl
   jl          loop
   pop         esi
   pop         ebx
exit:
   leave
   ret




какой код короче и понятнее с точки зрения компилятора и процессора?
имхо первый. во втором случае компилятору пришлось проделать гораздо больше работы,
чтобы соптимизировать код.
Re: Продолжение флейма к Areex
От: Areex  
Дата: 14.04.03 13:57
Оценка:
Здравствуйте, Awaken, Вы писали:

A>итак указатели vs индексы.

A>вот написал я более нетривиальный пример — реверс строки

A>какой код короче и понятнее с точки зрения компилятора и процессора?

A>имхо первый. во втором случае компилятору пришлось проделать гораздо больше работы,
A>чтобы соптимизировать код.

Мой компилятор с твоим ни разу не согласен. Что у тебя за чудо?
Хотя некоторое облажание в оптимизации на лице, основное отличие в eax+esi. Имхо, потерь в тактах нет, но врать не буду а справочника под рукой у меня нет. Кто-нибудь может сказать? В общем все от оптимизатора зависит, конструкции одинаковые.

    mov    ecx, DWORD PTR _source$[esp-4]
    mov    eax, DWORD PTR _len$[esp-4]
    add    eax, ecx
    cmp    ecx, eax
    jae    SHORT $L36331
    push    ebx
$L36330:
    mov    bl, BYTE PTR [eax]
    mov    dl, BYTE PTR [ecx]
    mov    BYTE PTR [ecx], bl
    inc    ecx
    mov    BYTE PTR [eax], dl
    dec    eax
    cmp    ecx, eax
    jb    SHORT $L36330
    pop    ebx
$L36331:
    ret    0

-----------------------------

    mov    ecx, DWORD PTR _len$[esp-4]
    xor    eax, eax
    test    ecx, ecx
    jle    SHORT $L36331
    push    ebx
    push    esi
    mov    esi, DWORD PTR _source$[esp+4]
$L36330:
    movsx    edx, BYTE PTR [eax+esi]
    mov    bl, BYTE PTR [ecx+esi]
    mov    BYTE PTR [eax+esi], bl
    inc    eax
    mov    BYTE PTR [ecx+esi], dl
    dec    ecx
    cmp    eax, ecx
    jl    SHORT $L36330
    pop    esi
    pop    ebx
$L36331:
    ret    0
"I dive through the fire."
Re[2]: Продолжение флейма к Areex
От: Awaken Украина  
Дата: 14.04.03 14:15
Оценка:
A>Мой компилятор с твоим ни разу не согласен. Что у тебя за чудо?

VC++ 6.0, SP5. включал кодогенерацию для Pentium Pro и optimize for speed
Re[3]: Продолжение флейма к Areex
От: Areex  
Дата: 14.04.03 14:26
Оценка:
Здравствуйте, Awaken, Вы писали:

A>>Мой компилятор с твоим ни разу не согласен. Что у тебя за чудо?


A>VC++ 6.0, SP5. включал кодогенерацию для Pentium Pro и optimize for speed


Что интересно аналогично, интересно откуда такие различия?
"Damn It, where did I put that slay dragon scroll?"
Re[4]: Продолжение флейма к Areex
От: Awaken Украина  
Дата: 14.04.03 15:12
Оценка:
A>Что интересно аналогично, интересно откуда такие различия?

могут влиять еще какие-то параметры компиляции которые я не трогал (оставил дефолтными)
Re: Продолжение флейма к Areex
От: mihailik Украина  
Дата: 15.04.03 09:40
Оценка:
A>итак указатели vs индексы.

Есть задачи, в которых нужно во что бы то ни стало оптимизировать скорость.

А есть задачи, в которых нужно во что бы то ни стало оптимизировать читабельность.

По скорости указатели может и выигрывают, но по читабельности-таки отстают. Вот и выбирай, что больше подходит. Я вот последнее время чаще забиваю на скорость в пользу чистоты и понятности кода. Пусть тормозит, зато глюков поменьше.

А есть монстры, которые рубят эти укзатели в щепки и прямо-таки жонглируют ими. Что ж, снимем перед ними шляпу. Правда такой указательный код нужно поусерднее комментировать.
... << RSDN@Home 1.0 beta 6a >>
Re[2]: Продолжение флейма к Areex
От: Awaken Украина  
Дата: 15.04.03 10:04
Оценка: :)
M>А есть задачи, в которых нужно во что бы то ни стало оптимизировать читабельность.

есть такие задачи. например задача написать статью для журнала
Re[3]: Продолжение флейма к Areex
От: mihailik Украина  
Дата: 15.04.03 11:56
Оценка:
M>>А есть задачи, в которых нужно во что бы то ни стало оптимизировать читабельность.

A>есть такие задачи. например задача написать статью для журнала


И не только. Если код слишком часто рассматривается, читается, исправляется — лучше забить на скорость. Например, в проектах с открытым кодом и с десятками разработчиков читабельность, по идее, достаточно важна.
... << RSDN@Home 1.0 beta 6a >>
Re[2]: Продолжение флейма к Areex
От: WolfHound  
Дата: 15.04.03 16:29
Оценка: 2 (2)
Здравствуйте, mihailik, Вы писали:

M>По скорости указатели может и выигрывают, но по читабельности-таки отстают.

    char src[]="iddqd, idkfa :-)"
    char dest[100];
    for(char* s=src, d=dest;*d++=*s++;);

ИМХО любой "плюснутый" без труда поймет что это.
Особенно если подобный код будет в процедуре Copy класса String.
... << RSDN@Home 1.0 beta 5 >>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[3]: Продолжение флейма к Areex
От: Areex  
Дата: 15.04.03 17:52
Оценка: 1 (1)
Здравствуйте, WolfHound, Вы писали:

WH>Здравствуйте, mihailik, Вы писали:


M>>По скорости указатели может и выигрывают, но по читабельности-таки отстают.

WH>
WH>    char src[]="iddqd, idkfa :-)"
WH>    char dest[100];
WH>    for(char* s=src, d=dest;*d++=*s++;);
WH>

WH>ИМХО любой "плюснутый" без труда поймет что это.
WH>Особенно если подобный код будет в процедуре Copy класса String.

Вопрос не в том поймет или нет, вопрос в том -- зачем?
for(int i=0; dest[i]=src[i]; i++); Даст точно такой же код.
Даже в нетривиальном, по словам awaken'a, случае выигрыш составляет 2 команды на функцию. push/pop
И то другой компилятор мог и не облажаться. Уж в твоём то случае, ничего рационального точно нет.
Я не утверждаю, что такое использование не имеет право на жизнь, но вот использовать постоянно смысла нет, это только снижает наглядность.
"Hah! I'm not dead yet. I still have five hit points."
Re[4]: Продолжение флейма к Areex
От: WolfHound  
Дата: 15.04.03 18:58
Оценка:
Здравствуйте, Areex, Вы писали:

A>for(int i=0; dest[i]=src[i]; i++); Даст точно такой же код.

А я спорю?

A>Я не утверждаю, что такое использование не имеет право на жизнь, но вот использовать постоянно смысла нет, это только снижает наглядность.

Возможно для начинающих, но для законченых ИМХО без разници. Я хотел сказать только это.

ЗЫ Что касается компиляторов то это монстры... Они даже виртуальные функции умудряются инлайнить
... << RSDN@Home 1.0 beta 5 >>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[5]: Продолжение флейма к Areex
От: Areex  
Дата: 16.04.03 05:47
Оценка:
Здравствуйте, WolfHound, Вы писали:


A>>Я не утверждаю, что такое использование не имеет право на жизнь, но вот использовать постоянно смысла нет, это только снижает наглядность.

WH>Возможно для начинающих, но для законченых ИМХО без разници. Я хотел сказать только это.

Если ты пишешь для себя то возможно, но если ты учавствуешь в проекты суппорт которого еще лет десять будет? Умно ли опираться на предположение, что все следующие за тобой будут "законченые"?

WH>Пусть это будет просто:

WH>просто, как только можно,
WH>но не проще.

Ась?
"Damn It, where did I put that slay dragon scroll?"
Re[3]: Продолжение флейма к Areex
От: mihailik Украина  
Дата: 16.04.03 12:54
Оценка:
M>>По скорости указатели может и выигрывают, но по читабельности-таки отстают.

WH>
WH>    for(char* s=src, d=dest;*d++=*s++;);
WH>

WH>ИМХО любой "плюснутый" без труда поймет что это.

Ну, тут уже ближе к "чувствам" вопрос. В данном случае довольно гладко, а вообще тенденция всё-таки, что индексы удобнее чем указатели читаются.
... << RSDN@Home 1.0 beta 6a >>
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.