На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! Правила раздела:
1. Название темы - краткое описание кто/что против кого/чего
2. В первом сообщении - список параметров, по которым идет сравнение.
3. Старайтесь аргументировать свои высказывания. Фразы типа "Венда/Слюникс - ацтой" считаются флудом.
4. Давайте жить дружно и не доводить обсуждение до маразма и личных оскорблений.
Модераторы: Модераторы, Комодераторы
Страницы: (31) « Первая ... 16 17 [18] 19 20 ...  30 31  ( Перейти к последнему сообщению )  
> идеальный язык программирования , каким он должен быть?
    Цитата AndNot @
    :yes: В принципе с ним все ясно. Еща одна попытка чисто ООП программирования. Попытка оградить программиста от железа. Это слишком высокоуровневый язык, что бы тянуть на идеальный.

    Я ж говорю если нужна именно скорость тогда твой выбор 100% не Python. Однако если тебе важны: классы, высокоуровневые структуры данных и подобное тогда Python это как раз то что доктор прописал. Благодаря всему этому даже математика на Python это наслаждение. Я это понял после того как пробился с комплексными в Delphi это было что то. Я молчу о вводе/выводе :whistle: но даже сам поиск ошибок это был такой трах! Для Python комплексная математика вообще оказалась пустяком. ;)

    Цитата AndNot @
    Не надо так категорично, подозреваю что по скорости он им здорово проиграет, по крайней мере С.

    Подозреваешь верно! :yes: Я сравнивал один и тот же (код) алгоритм на Python и на Delphi 7... Delphi выиграл по скорости в 5 раз. Но если учесть все ньюансы... К примеру в Python все переменные по умолчанию это классы! 8-) Все преобразования типов интерпретатор Python берет на себя. Т.е. если нет особого желания явно работать с преобразованиями типов к примеру как в Delphi то все сам сделает Python за сценой... Соответственно ошибки отсеиваются нааамного интенсивнее но при этом тратится время.

    Цитата mo3r @
    Эффективность и скорость исполнения программы — вещи, не связанные напрямую.

    :yes: Правильно сказано!

    Поэтому IMHO идеальной была бы связка в виде:
    Человек
    1) Язык(Языки) высокого уровня
    2) Парсер языка(языков) высокого уровня преобразующий код в asm
    3) Компилятор ASMa
    Машина

    Достоинства:
    решает языковую проблему! Языком высокого уровня может быть что угодно. А при грамотно написанном парсере можно будет даже использовать все достоинства всех языков. Нечто вроде html к примеру вставил
    Цитата
    <pascal>begin end </pascal>
    и понесся :P надо хардкора вставил
    Цитата
    <asm></asm>
    и лови свой кайф. Тем не менее остается место и для охочих до скорости (asm) и простор для совершенствования как самого языка высокого уровня так и остальных звеньев цепочки...

    А вот кстати та темка где я скорость работы Python и Delphi сравнивал Python vs Delphi
      Цитата best_lamer @
      Я ж говорю если нужна именно скорость тогда твой выбор 100% не Python. Однако если тебе важны: классы, высокоуровневые структуры данных и подобное тогда Python это как раз то что доктор прописал. Благодаря всему этому даже математика на Python это наслаждение. Я это понял после того как пробился с комплексными в Delphi это было что то. Я молчу о вводе/выводе :whistle: но даже сам поиск ошибок это был такой трах! Для Python комплексная математика вообще оказалась пустяком. ;)

      ИМХО, можно вкратце сказать так: можно выделить два класса ситуаций, когда нужна высокая производительность:
      1) Реал-тайм
      2) Большие объемы данных;
      Идеальный язык должен быть доступен в этих двух областях (а так же в областях, не критичных по производительности кода, но критичных по производительности программиста); java и .net, например, никак не подходят к реал-тайму.
        Цитата best_lamer @
        Все преобразования типов интерпретатор Python берет на себя. Т.е. если нет особого желания явно работать с преобразованиями типов к примеру как в Delphi то все сам сделает Python за сценой... Соответственно ошибки отсеиваются нааамного интенсивнее но при этом тратится время.

        Кто бы спорил.
        Цитата best_lamer @
        Поэтому IMHO идеальной была бы связка в виде:
        Человек
        1) Язык(Языки) высокого уровня
        2) Парсер языка(языков) высокого уровня преобразующий код в asm
        3) Компилятор ASMa
        Машина

        Да я доказывая это уже всю клаву разбил. Просто предложил Форт как готовую основу в качестве посредника/парсера.
          Цитата AndNot @
          Да я доказывая это уже всю клаву разбил. Просто предложил Форт как готовую основу в качестве посредника/парсера.

          Прошу прощения я тему с самого начала не читал :huh:
            Цитата AndNot @
            Причем здесь приоритет? Дело то в том, что после умножения DWORD на DWORD результат получается QWORD, который может просто не влезть в int. И деление после этого логично производить именно от промежуточного результата, а я наблюдал другую картину :(

            Ах, вот ты про что...
            Ну, не влез, и чего? (кстати, беря в руки твоё же оружие: в том же x86-ассеблере можно написать imul eax,ebx - eax*ebx помещается в eax - тоже ведь возможно усечение результата).
            Пусть написали int x = a * b / c. Помещать a*b в QWORD? А если c == 1, то кирдык, и у нас опять усечение при помещении результата в x? Или int x = a * b * c. Тут чего делать?
            От усечения не избавиться. Предложенная тобой схема только оттянет конец (избавив от первого возможного усечения).

            Цитата
            Цитата Hryak @
            Зато простое и реальное.

            Это все равно, что мол не нравится винда, ставь другую систему. Только вот аналогичных что-то не вижу :wall:

            При чем тут винда? Конкуренция есть в довольно многих областях софтонаписания.

            Цитата
            Цитата Hryak @
            Этого нет. Да и разумность этого крайне невелика, имхо.

            Это потому что ты ими не пользуешся ;) Но иногда очень сильно сокращает код.

            Ты что, для микроконтроллеров пишешь? Нахрен такое сокращение на фоне геммора с поддержкой такого кода.
            Да и обычно в программах длина кода не сильно заметна на фоне длины кода подгружаемых библиотек и длины данных, размещаемых этой программой в памяти.

            Цитата
            Ну почему именно константа? Меня больше интересует как он адрес будет вычислять, и соответственно после этого инвертировать.

            ExpandedWrap disabled
              ;bs.flip(i);
                mov         edx,ecx  // в ecx находится i
                shr         edx,5
                lea         eax,bs (433B08h)[edx*4]
                and         ecx,1Fh
                mov         edx,1
                shl         edx,cl
                xor         dword ptr [eax],edx
                Цитата Hryak @
                Ну, не влез, и чего?

                Ну у меня бывали трудновылавливаемые ошибки из-за подобного кода.
                Цитата Hryak @
                (кстати, беря в руки твоё же оружие: в том же x86-ассеблере можно написать imul eax,ebx - eax*ebx помещается в eax - тоже ведь возможно усечение результата)

                Если ты применяешь imul, то осознанно (например при вычислении адреса видеопамяти, где результат в принципе не выйдет за диапозон), и отловить переполнение несложно с помощью флагов, а когда нужна гарантия достоверности результата пишеш:
                ExpandedWrap disabled
                  mov eax,[xx]
                  mul [yy]
                  div [zz]

                и все. А вот в ЯВУ нет никаких средств проконтролировать подобные ситуации.
                Цитата Hryak @
                Помещать a*b в QWORD? А если c == 1, то кирдык, и у нас опять усечение при помещении результата в x?

                Во первых не усечение а исключение 0, соответственно обработчик отловит и примет меры ;) . А во вторых, если результат умножения усекать, то просто получишь неверный результат, и подобную ситуацию трудно выявить.
                Цитата Hryak @
                Или int x = a * b * c

                Это из другой области.
                Цитата Hryak @
                Да и обычно в программах длина кода не сильно заметна на фоне длины кода подгружаемых библиотек и длины данных, размещаемых этой программой в памяти.

                Ага, особенно когда Дельфовские запускаешь :lol:
                Да и почему не воспользоваться, если возможность подвернется.
                Цитата Hryak @

                ExpandedWrap disabled
                  ;bs.flip(i);
                  mov         edx,ecx  // в ecx находится i
                  shr         edx,5
                  lea         eax,bs (433B08h)[edx*4]
                  and         ecx,1Fh
                  mov         edx,1
                  shl         edx,cl
                  xor         dword ptr [eax],edx


                Ужас, теперь всю ночь спать не буду ;)
                Можно ведь и проще:
                ExpandedWrap disabled
                  mov eax,[i] ; i - номер бита
                  btc [BitField],eax

                Вроде получше, можно получить доступ к любому из 2^31 биту ;)
                И насчет выразительности Си и Форта ;) Забрел на сайтик, и прикололся, автор явно лучше меня знает Си:
                Цитата

                Другая "особенность"
                char str[50]="qwertyuio";
                int a=3;str[++a]=str[++a]=' ';
                cout<<str<<"\n";
                str[a++]=str[a++]=' ';
                cout<<str<<"\n";
                Результат:
                qwe tyuio
                qwert uio
                По логике вещей должны быть добавлены два пробела. Но у C своя логика, так что это не ошибка компилятора, а особенность языка.
                int i=0,ar[2]={10,11};
                i=ar[i++];// А кто сразу скажет чему равно значение i

                Цитата

                Примеры:

                Паскаль:
                if Screen.Forms[I] is FormClass then begin

                C++:
                if (dynamic_cast<FormClass*>(Screen - >Forms[I])){
                A=(!CL&&!RC)?0 : (!LC?RC:LC)//"Очень понятное выражение"
                *++* agrv //"Еще одно очень понятное выражение, при том синтаксически верное"
                "Интуитивно понятный" синтаксис прекрасно подчеркивает следующий пример:
                int i=5;
                int * const p3=&i;//Указатель константу
                const int * p3=&i;//Указатель на константу
                i=5;//Правильно
                *p3=5; Неверно! указатель на константу измененную в предыдущей строке.

                char (*(*x2 ())[]) () //Срочно позовите криптоаналитика !!!
                Или работа с перечислениями:
                enum modes { LASTMODE , BW40 , C40, BW80, C80, MONO } ;
                ..
                modes e1=C80,e2;
                e1=e2*3; //Очень осмысленный оператор на "ЯПВУ".
                //Ведь для "ЯПВУ" нет разницы, что int, что enum, что bool

                А что может значить, по Вашему мнению, команда a=24[ar]; ?
                При условии, что int ar[50]; int a; она полностью эквивалентна a:=ar[24];
                Как совершенно справедливо замечают поклонники C/C++ эти языки позволяют писать чрезвычайно краткие и выразительные программы. На счет краткости - безусловно.
                А вот к какой выразительности может привести краткость, я сейчас покажу:
                #include <stdio.h>
                #define Q r=R[*p++ - '0'];while(
                #define B ;break;case
                char*s="Qjou!s\\311^ - g\\311^ - n\\311^ - c\\::^ - q - ma%mO1JBHm%BQ - aP1J[O1HB%[Q<nbj\
                o)*|gps)<<*txjudi)m*|aQdbtf!::::;sfuvso<aQefgbvmu;aQ<m,,a%CQ<csfbla%bQ<aN2!Q\
                \ndbtf!aP2Q;m>aP2Q<a%!D12J!JGJHJOJQJFJSJJJMHS%HD12D12N3!N4\nJUJT%UQm>aP4HC%T\
                Qs\\q,,^>m,2<m>aP4HC%SD12N1\nJNQm>s\\..q^aHC%NHb%GN1!D32P3%RN1UP1D12JPQUaP1H\
                R%PN4\nQ<g\\(aP3Q(^>aP2Q,2<n\\(aP3Q(^>aP4Hb%OD12D12N2!N3\nJVP3Q,,<jg)aP3Q=>n\
                \\(aP3Q(^*m>g\\(aP3Q(^<fmtf!m,,aHC%QN1!N1\nJ#Qqsjoug)#&e]o# - aP1Q*aHb%#Qqvut)\
                aP1Q*aHb%FN1\nQm>::::aHC%VP3Q>bupj)hfut)c**aHb%JD12JON1!Qjg)a%LN1UP1D12JIQUa\
                P1HL%IQ*m>aN2!N2\nP2Q<fmtf!m,,aHC%MN1!N2>P2Q>aN2\nP2Hbdd!b/d";int k;char R[4][99]
                ;main(c,v)char**v;{char*p,*r,*q;for(q=s;*q;q++)*q>' '&&(*q) - - ;{FILE*i=fopen(v
                [1],"r"),*o=fopen(q - 3,"w");for(p=s;;p++)switch(*p++){B'M':Q(k=fgetc(i))!=EOF
                &&k!=*p)*r++=k;if(k==EOF){fputs("}}\n",o);fclose(o);return system(q - 6);}*r=0
                B'P':while(*p!='`')fputc(*p++,o)B'O':Q*r)fputc(*r++,o);p - - B'C':k=0;Q k<*p - '0'
                )(*r++=fgetc(i),k++);*r=0 B'I':k= *p;if(**R==k)goto G B'G':k= *p;G:p=s;while(
                *p!='$'||p[1]!= k)p++;p++B'N':R[*p - '0'][0]++;}}}

                Эта программа всего в 17 строчках текстового режима VGA(25X80) представляет собой полнофункциональный интерпретатор языка Basic, который поддерживает:
                Переменные(имена от A до Z), которые инициализируются нулевыми значениями при запуске.
                Цикл FOR var = exp TO exp ..NEXT var
                Подпрограммы GOSUB exp и RETURN
                Естественно, оператор GOTO(какой же Basic без GOTO)
                Условия IF exp THEN exp
                Комментарий REM any text
                Оператор конец программы END
                Присвоение var = exp
                Ввод INPUT variable
                И вывод PRINT string PRINT exp
                Есть ли читатели, которые по - прежнему считают, что краткость - это всегда очень хорошо. А читабельность конструкций языка факт второстепенный ?

                Цитата

                Кстати, многие средства языка, которые, по мнению его поклонников, появились в C++, были заимствованы из других языков. К примеру, аналог шаблонов - пакеты - были в АДЕ до создания C++. Обработка исключительных ситуаций присутствует в АДЕ и даже в PL/1.Перезагрузка операций также присутствовала в АДЕ.

                Copyright© Костин Г.В., 2003

                Кстати что то за Аду еще никто не вставил две копейки.
                  Цитата AndNot @
                  а когда нужна гарантия достоверности результата пишеш:
                  ExpandedWrap disabled
                    mov eax,[xx]
                    mul [yy]
                    div [zz]

                  и все.

                  Еще раз. Хорошо, частный случай неплохо обработал. Что будешь делать с xx*yy*zz/aa ?

                  Цитата
                  Цитата Hryak @
                  Помещать a*b в QWORD? А если c == 1, то кирдык, и у нас опять усечение при помещении результата в x?

                  Во первых не усечение а исключение 0, соответственно обработчик отловит и примет меры ;)

                  Не понял - откуда исключение? :blink:


                  Цитата
                  Цитата Hryak @
                  Да и обычно в программах длина кода не сильно заметна на фоне длины кода подгружаемых библиотек и длины данных, размещаемых этой программой в памяти.

                  Ага, особенно когда Дельфовские запускаешь :lol:

                  Не про делфи разговор :D. Да и я не точно высказался - под "длиной кода" имел в виду длину кода, написанную собственноручно программистом, а не заимствованную из библиотек.

                  Цитата
                  Да и почему не воспользоваться, если возможность подвернется.

                  А что, по-твоему, читаемость программы не уменьшится при этом?

                  Цитата
                  Цитата Hryak @

                  ExpandedWrap disabled
                    ;bs.flip(i);
                    mov         edx,ecx  // в ecx находится i
                    shr         edx,5
                    lea         eax,bs (433B08h)[edx*4]
                    and         ecx,1Fh
                    mov         edx,1
                    shl         edx,cl
                    xor         dword ptr [eax],edx


                  Ужас, теперь всю ночь спать не буду ;)
                  Можно ведь и проще:
                  ExpandedWrap disabled
                    mov eax,[i] ; i - номер бита
                    btc [BitField],eax

                  Кому проще-то? Программисту? Так ведь не он это пишет, а компилятор.

                  Цитата
                  Вроде получше

                  Кому лучше? Компилятору? А ты уверен, что твой код быстрее будет выполняться, чем показанный мной? Зуб дашь?

                  Цитата
                  Забрел на сайтик, и прикололся, автор явно лучше меня знает Си:
                  Цитата

                  Другая "особенность"
                  ...
                  По логике вещей должны быть добавлены два пробела. Но у C своя логика, так что это не ошибка компилятора, а особенность языка.
                  ....
                  i=ar[i++];// А кто сразу скажет чему равно значение i
                  ....

                  Все пляски вокруг всё того же (++i)++ - достаточно один раз запомнить, чтобы не наступать на эти грабли.

                  Цитата
                  Паскаль:
                  if Screen.Forms[I ] is FormClass then begin

                  C++:
                  if (dynamic_cast<FormClass*>(Screen - >Forms[I ])){

                  Ой, чуть длиннее, сахара мало положили. Зато все преобразования (static_cast, dynamic_cast, reinterpret_cast, const_cast) имеют одинаковый вид.

                  Цитата
                  "Интуитивно понятный" синтаксис прекрасно подчеркивает следующий пример:
                  int i=5;
                  int * const p3=&i;//Указатель константу
                  const int * p3=&i;//Указатель на константу

                  Всё, что данный пример подчеркивает - дак это то, что "авторитет", писавший эту статью, не знает C++ даже на уровне одного семестра изучения в институте. int * const p3 - это не указатель константу, а константный указатель. Правило построения определений в C/C++ очень простое - просто его надо знать.

                  Цитата
                  char (*(*x2 ())[]) () //Срочно позовите криптоаналитика !!!

                  0. Крипноаналитик не нужен - выражение довольно легко читается программистом на C/C++.
                  1. Не зови крипноаналитика и не используй указатели на функции (или пиши на языке, который не позволяет их использовать).
                  2. Если не хочешь никого запутывать, вместо
                  ExpandedWrap disabled
                    char (*(*x2 ())[]) ();
                  напиши
                  ExpandedWrap disabled
                    typedef char func();
                    typedef func* arr[];
                    arr* x2();
                  Это даже самый начинающий программист на C/C++ прочтёт.

                  Цитата
                  Или работа с перечислениями:
                  enum modes { LASTMODE , BW40 , C40, BW80, C80, MONO } ;
                  ..
                  modes e1=C80,e2;
                  e1=e2*3;

                  Не скомпилируется на C++.

                  Цитата
                  А что может значить, по Вашему мнению, команда a=24[ar]; ?

                  Никто не заставляет так писать.

                  Цитата
                  A=(!CL&&!RC)?0 : (!LC?RC:LC)//"Очень понятное выражение"
                  *++* agrv //"Еще одно очень понятное выражение, при том синтаксически верное"
                  ....
                  А вот к какой выразительности может привести краткость, я сейчас покажу:

                  Привело, и что? На любом языке можно писать нечитаемые программы. Что из этого следует?

                  Цитата
                  Кстати, многие средства языка, которые, по мнению его поклонников, появились в C++, были заимствованы из других языков. К примеру, аналог шаблонов - пакеты - были в АДЕ до создания C++. Обработка исключительных ситуаций присутствует в АДЕ и даже в PL/1.Перезагрузка операций также присутствовала в АДЕ.

                  Вроде Бьярн никогда и не скрывал, откуда он чего позаимствовал. Чего в этом плохого-то?
                  "Перезагрука" :lool: :lool: :lool:

                  Цитата
                  Кстати что то за Аду еще никто не вставил две копейки.

                  А чего за неё вставлять? Приложения, насколько я знаю, получаются сверхнадежными, но и писать их сверхсложно.
                    Цитата Hryak @
                    Приложения, насколько я знаю, получаются сверхнадежными, но и писать их сверхсложно


                    this language for american soldiers only
                    :lool: :lool: :lool:

                    Добавлено
                    Цитата AndNot @
                    Цитата (impik777 @ Вчера, 15:43)
                    а для чего по твоему существует инкапсуляция, контроль типов и т.д.


                    блин, ну причем здесь ошибки логики программы?


                    ошибки логики становятся ошибками синтаксиса, а их отслеживает компилятор
                    блин, ты почитай про современные методы проектирования и программирования ;)

                    Добавлено
                    Цитата AndNot @
                    Цитата (impik777 @ Вчера, 15:43)
                    в примитиве ini файл
                    более глубоко - использование интерпретирующихся скриптов

                    Это отстой а не программа, если она может заглючить от неверно прописанного INI.


                    да, и почему большинство серьезных игр и EIS'ок имеют скрипты и ini файлы ???? :D :D

                    Добавлено
                    Цитата AndNot @
                    Забрел на сайтик

                    :lool: :lool: :lool: :lool: :lool: :lool: :lool: :lool:
                    да, такой хохмы я давно не видел,
                    новички в университетах, и то так не пишут,
                    а уж они перлы выдают те еще,

                    Добавлено
                    Цитата AndNot @
                    #include <stdio.h>
                    #define Q r=R[*p++ - '0'];while(
                    #define B ;break;case
                    char*s="Qjou!s\\311^ - g\\311^ - n\\311^ - c\\::^ - q - ma%mO1JBHm%BQ - aP1J[O1HB%[Q<nbj\
                    o)*|gps)<<*txjudi)m*|aQdbtf!::::;sfuvso<aQefgbvmu;aQ<m,,a%CQ<csfbla%bQ<aN2!Q\
                    \ndbtf!aP2Q;m>aP2Q<a%!D12J!JGJHJOJQJFJSJJJMHS%HD12D12N3!N4\nJUJT%UQm>aP4HC%T\
                    Qs\\q,,^>m,2<m>aP4HC%SD12N1\nJNQm>s\\..q^aHC%NHb%GN1!D32P3%RN1UP1D12JPQUaP1H\
                    R%PN4\nQ<g\\(aP3Q(^>aP2Q,2<n\\(aP3Q(^>aP4Hb%OD12D12N2!N3\nJVP3Q,,<jg)aP3Q=>n\
                    \\(aP3Q(^*m>g\\(aP3Q(^<fmtf!m,,aHC%QN1!N1\nJ#Qqsjoug)#&e]o# - aP1Q*aHb%#Qqvut)\
                    aP1Q*aHb%FN1\nQm>::::aHC%VP3Q>bupj)hfut)c**aHb%JD12JON1!Qjg)a%LN1UP1D12JIQUa\
                    P1HL%IQ*m>aN2!N2\nP2Q<fmtf!m,,aHC%MN1!N2>P2Q>aN2\nP2Hbdd!b/d";int k;char R[4][99]
                    ;main(c,v)char**v;{char*p,*r,*q;for(q=s;*q;q++)*q>' '&&(*q) - - ;{FILE*i=fopen(v
                    [1],"r"),*o=fopen(q - 3,"w");for(p=s;;p++)switch(*p++){B'M':Q(k=fgetc(i))!=EOF
                    &&k!=*p)*r++=k;if(k==EOF){fputs("}}\n",o);fclose(o);return system(q - 6);}*r=0
                    B'P':while(*p!='`')fputc(*p++,o)B'O':Q*r)fputc(*r++,o);p - - B'C':k=0;Q k<*p - '0'
                    )(*r++=fgetc(i),k++);*r=0 B'I':k= *p;if(**R==k)goto G B'G':k= *p;G:p=s;while(
                    *p!='$'||p[1]!= k)p++;p++B'N':R[*p - '0'][0]++;}}}



                    :lool: :lool: :lool: :lool: :lool: :lool: :lool: :lool:
                    валяюсь под столом
                    Сообщение отредактировано: impik777 -
                      Цитата Hryak @
                      Еще раз. Хорошо, частный случай неплохо обработал. Что будешь делать с xx*yy*zz/aa ?

                      Можно хотя бы и так:
                      ExpandedWrap disabled
                        mov eax,[xx]
                        imul [yy]
                        jc  __long_mul ; результат не умещается в edx:eax, уходим на длинную арифметику
                        imul [zz]
                        jc  __long_mul2
                        idiv [aa]

                      Гарантированно получишь корректный результат ;)
                      Цитата Hryak @
                      Цитата
                      Цитата

                      Цитата

                      (Hryak @ 15.10.06, 20:54)
                      Помещать a*b в QWORD? А если c == 1, то кирдык, и у нас опять усечение при помещении результата в x?

                      Во первых не усечение а исключение 0, соответственно обработчик отловит и примет меры ;)

                      Не понял - откуда исключение? :blink:

                      Если, при выполнении деления, результат(частное) не умещается в регистр, то процессор генерит "исключение 0 - переполнение при делении, или деление на ноль"(тип Fault), сохраняет в стеке адрес бад-команды и передает управление обработчику исключения. Понял в чем кайф? И если программа не установила свой обработчик, то винда просто завершит программу.
                      Цитата Hryak @
                      Цитата
                      Да и почему не воспользоваться, если возможность подвернется.

                      А что, по-твоему, читаемость программы не уменьшится при этом?

                      Частенько наоборот, читаемость улучшается, за счет сокращения размера сорсов (актуально для асма).
                      Цитата Hryak @
                      Кому проще-то? Программисту? Так ведь не он это пишет, а компилятор.

                      А разговор начинался про средства оптимизации компиляторов ЯВУ, а они, как показывает практика, частенько тупят. Даже интеловский Си бывает выдает ляпы.
                      С другой стороны сам вопрос об оптимизации спорный. Уже давно процессоры сами меняют очередность команд, используют переименование регистров и прочие трюки. Так что о распаралеливании команд в сорсах можно в принципе и не задумываться, особо заметного проигрыша не будет. А вообще говоря об оптимизации что имеется в виду? Архитектур много, и если на одном процессоре получищь большой прирост по скорости, то на другом, скорее всего, получишь охрененные тормоза. Где золотая середина?
                      Цитата Hryak @
                      Цитата

                      Вроде получше


                      Кому лучше? Компилятору? А ты уверен, что твой код быстрее будет выполняться, чем показанный мной? Зуб дашь?

                      Даже больше чем уверен, хотя бы потому, что сдвиги с операндом в CL не спариваются (как и BTC), и времени жрет как и BTC. Так что код компилятора не просто плохой, он отвратительный, наглядный пример как не надо делать.
                      Цитата impik777 @
                      ошибки логики становятся ошибками синтаксиса

                      С какого перепуга :wacko:
                      Цитата impik777 @
                      да, и почему большинство серьезных игр и EIS'ок имеют скрипты и ini файлы ????

                      Я не про это. Читай внимательнее.
                      Ну а теперь всем сразу по поводу приведенных перлов Си.
                      Главное не то как на нем большинство пишет, главное что он позволяет такую чушь писать.
                      Цитата

                      "С точки зрения теоретического программирования язык си - это Фортран 80 - ых. (Против такого уничижительного определения не возражал и автор языка Си - Д. Ритчи). Этот язык, сочетающий в себе многие преимущества языка высокого уровня и ассемблера, дал программистам, по образному выражению некоторых, педаль газа, но заблокировал педаль тормоза. На Си компьютер может "мчаться" быстро, но рискованно. То есть Си, насаждая ссылочно - ассемблерное программирование, как бы имеет вектор в сторону, противоположную той, которая определяется теорией и методологией языков программирования.
                      Поэтому и Си++ - это довольно странное сочетание некоторых черт ООП (здесь и далее - объектно - ориентированное программирование) и процедурного программирования"
                      К.Т.Н. Соловьев А.Е.
                        Цитата AndNot @
                        Цитата Hryak @
                        Еще раз. Хорошо, частный случай неплохо обработал. Что будешь делать с xx*yy*zz/aa ?

                        Можно хотя бы и так:
                        ExpandedWrap disabled
                          mov eax,[xx]
                          imul [yy]
                          jc  __long_mul ; результат не умещается в edx:eax, уходим на длинную арифметику
                          imul [zz]
                          jc  __long_mul2
                          idiv [aa]

                        Гарантированно получишь корректный результат ;)

                        Т.е. будет ветка с нормальной арифметикой, ветка с длинной, со сверхдлинной и т.д. А результат куда денешь? Тоже будешь делать нормальный результат, длинный результат, сверхдлинный результат и т.д.? А потом этот результат будет использоваться в другом выражении - там все повторится в коде, но уже три раза (по разу на каждый вариант предыдущего шага). Колонии микробов в плане размножения отдыхают. :lool:

                        Цитата
                        Если, при выполнении деления, результат(частное) не умещается в регистр, то процессор генерит "исключение 0 - переполнение при делении, или деление на ноль"(тип Fault), сохраняет в стеке адрес бад-команды и передает управление обработчику исключения.

                        Понятно, я сразу не понял о чем речь.

                        Цитата
                        Цитата Hryak @
                        А что, по-твоему, читаемость программы не уменьшится при этом?

                        Частенько наоборот, читаемость улучшается, за счет сокращения размера сорсов (актуально для асма).

                        Не знаю, что там актуально для асма (не спец), но для языков высокого уровня бóльшее значение имеет упорядоченность исходников и простота взаимосвязей кода. И то, и другое будет страдать от подобных фишек. И если при программировании на языке высокого уровня проявляется желание в конкретном месте поюзать такое - значит пришло время для выделения части кода в отдельную функцию.

                        Цитата
                        А разговор начинался про средства оптимизации компиляторов ЯВУ, а они, как показывает практика, частенько тупят. Даже интеловский Си бывает выдает ляпы.

                        Ничего совершенного не существует. Ляпы оптимизатора - фигня, если язык позволяет писать гораздо быстрее, ненапряжнее и надежнее код, чем ассемблер, а уж существенные ляпы, резко снижающие скорость выполнения критичных участков кода так, что это становится заметно, можно и ручками переписать на том же асме.

                        Цитата
                        С другой стороны сам вопрос об оптимизации спорный. Уже давно процессоры сами меняют очередность команд, используют переименование регистров и прочие трюки. Так что о распаралеливании команд в сорсах можно в принципе и не задумываться, особо заметного проигрыша не будет. А вообще говоря об оптимизации что имеется в виду? Архитектур много, и если на одном процессоре получищь большой прирост по скорости, то на другом, скорее всего, получишь охрененные тормоза. Где золотая середина?

                        Золотая середина как раз в языках высокого уровня. :) При компиляции исходника я могу выставить, под какой процессор мне проводить оптимизацию. Можно сделать несколько версий программы путем простого перекомпилирования с нужными ключами. .NET пошел еще дальше - компиляция перед первым запуском кода на клиенте, учитывая тип его процессора.

                        Цитата
                        Цитата Hryak @
                        Цитата

                        Вроде получше

                        Кому лучше? Компилятору? А ты уверен, что твой код быстрее будет выполняться, чем показанный мной? Зуб дашь?

                        Даже больше чем уверен, хотя бы потому, что сдвиги с операндом в CL не спариваются (как и BTC), и времени жрет как и BTC. Так что код компилятора не просто плохой, он отвратительный, наглядный пример как не надо делать.

                        inc eax дольше чем add eax,1 loopnz работает дольше чем sub ecx,1 jnz; на большинстве современных процов. btc - сложная инструкция по определению. Поэтому я решил накидать маленький тест. Попрошу тебя прокомментировать результаты:

                        Исходный код на C++:
                        ExpandedWrap disabled
                          #include <iostream>
                          #include <bitset>
                           
                          #include <Windows.h>
                           
                          const int nbits = 300000;
                          std::bitset<nbits> bs;
                           
                          void DoFlip(int cnt)
                          {
                              for (int i = 0; i < cnt; ++i)
                              {
                                  for (int j = 0; j < nbits; ++j)
                                      bs.flip(j);
                              }
                          }
                           
                          void DoBtc(int cnt)
                          {
                              for (int i = 0; i < cnt; ++i)
                              {
                                  for (int j = 0; j < nbits; ++j)
                                  {
                                      __asm
                                      {
                                          mov eax,j
                                          btc bs, eax // исключительно в целях теста
                                      }
                                  }
                              }
                          }
                           
                          #pragma inline_depth(0)
                           
                          int main()
                          {
                              int i;
                              std::cin >> i;
                           
                              DWORD st;
                           
                              st = GetTickCount();
                              DoFlip(i);
                              std::cout << "DoFlip time: " << GetTickCount()-st << " ms\n";
                           
                              st = GetTickCount();
                              DoBtc(i);
                              std::cout << "DoBtc time:  " << GetTickCount()-st << " ms\n";
                          }

                        Последствия работы компилятора (VC++8.0):
                        ExpandedWrap disabled
                          DoBtc:
                          0041AAF0  push        ecx
                          0041AAF1  test        eax,eax
                          0041AAF3  jle         DoBtc+2Dh (41AB1Dh)
                          0041AAF5  mov         edx,eax
                          0041AAF7  xor         ecx,ecx
                          0041AAF9  mov         dword ptr [esp],ecx
                          0041AAFC  lea         esp,[esp]
                          0041AB00  mov         eax,dword ptr [esp]
                          0041AB03  btc         dword ptr [bs (4237F8h)],eax
                          0041AB0A  add         ecx,1
                          0041AB0D  cmp         ecx,493E0h
                          0041AB13  mov         dword ptr [esp],ecx
                          0041AB16  jl          DoBtc+10h (41AB00h)
                          0041AB18  sub         edx,1
                          0041AB1B  jne         DoBtc+7 (41AAF7h)
                          0041AB1D  pop         ecx
                          0041AB1E  ret
                          ......
                          DoFlip:
                          0041AB20  push        ecx
                          0041AB21  push        ebx
                          0041AB22  push        esi
                          0041AB23  xor         esi,esi
                          0041AB25  test        edi,edi
                          0041AB27  jle         DoFlip+44h (41AB64h)
                          0041AB29  lea         esp,[esp]
                          0041AB30  xor         eax,eax
                          0041AB32  cmp         eax,493E0h
                          0041AB37  jae         DoFlip+48h (41AB68h)
                          0041AB39  mov         ecx,eax
                          0041AB3B  shr         ecx,5
                          0041AB3E  lea         edx,bs (4237F8h)[ecx*4]
                          0041AB45  mov         ecx,eax
                          0041AB47  and         ecx,1Fh
                          0041AB4A  mov         ebx,1
                          0041AB4F  shl         ebx,cl
                          0041AB51  add         eax,1
                          0041AB54  xor         dword ptr [edx],ebx
                          0041AB56  cmp         eax,493E0h
                          0041AB5B  jl          DoFlip+17h (41AB37h)
                          0041AB5D  add         esi,1
                          0041AB60  cmp         esi,edi
                          0041AB62  jl          DoFlip+10h (41AB30h)
                          0041AB64  pop         esi
                          0041AB65  pop         ebx
                          0041AB66  pop         ecx
                          0041AB67  ret
                          0041AB68  jmp         std::bitset<300000>::_Xran (402660h)
                          ........
                          int main()
                          {
                          0041AB70  push        ebp
                          0041AB71  mov         ebp,esp
                          0041AB73  and         esp,0FFFFFFF8h
                          0041AB76  push        ecx
                          0041AB77  push        ebx
                          0041AB78  push        esi
                          0041AB79  push        edi
                              int i;
                              std::cin >> i;
                          0041AB7A  lea         eax,[esp+0Ch]
                          0041AB7E  push        eax
                          0041AB7F  call        std::basic_istream<char,std::char_traits<char> >::operator>> (401F60h)
                           
                              DWORD st;
                           
                              st = GetTickCount();
                          0041AB84  mov         esi,dword ptr [__imp__GetTickCount@0 (41C000h)]
                          0041AB8A  call        esi
                              DoFlip(i);
                          0041AB8C  mov         edi,dword ptr [esp+0Ch]
                          0041AB90  mov         ebx,eax
                          0041AB92  call        DoFlip (41AB20h)
                              std::cout << "DoFlip time: " << GetTickCount()-st << " ms\n";
                          0041AB97  push        41E728h
                          0041AB9C  push        ecx
                          0041AB9D  call        esi
                          0041AB9F  sub         eax,ebx
                          0041ABA1  push        eax
                          0041ABA2  push        ecx
                          0041ABA3  push        41E730h
                          0041ABA8  push        offset std::cout (4235F8h)
                          0041ABAD  call        std::operator<<<std::char_traits<char> > (4059C0h)
                          0041ABB2  add         esp,0Ch
                          0041ABB5  push        eax
                          0041ABB6  call        std::basic_ostream<char,std::char_traits<char> >::operator<< (401DA0h)
                          0041ABBB  add         esp,4
                          0041ABBE  push        eax
                          0041ABBF  call        std::operator<<<std::char_traits<char> > (4059C0h)
                          0041ABC4  add         esp,8
                           
                              st = GetTickCount();
                          0041ABC7  call        esi
                          0041ABC9  mov         ebx,eax
                              DoBtc(i);
                          0041ABCB  mov         eax,edi
                          0041ABCD  call        DoBtc (41AAF0h)
                              std::cout << "DoBtc time:  " << GetTickCount()-st << " ms\n";
                          0041ABD2  push        41E740h
                          0041ABD7  push        ecx
                          0041ABD8  call        esi
                          0041ABDA  sub         eax,ebx
                          0041ABDC  push        eax
                          0041ABDD  push        ecx
                          0041ABDE  push        41E748h
                          0041ABE3  push        offset std::cout (4235F8h)
                          0041ABE8  call        std::operator<<<std::char_traits<char> > (4059C0h)
                          0041ABED  add         esp,0Ch
                          0041ABF0  push        eax
                          0041ABF1  call        std::basic_ostream<char,std::char_traits<char> >::operator<< (401DA0h)
                          0041ABF6  add         esp,4
                          0041ABF9  push        eax
                          0041ABFA  call        std::operator<<<std::char_traits<char> > (4059C0h)
                          0041ABFF  add         esp,8
                          }
                          0041AC02  pop         edi
                          0041AC03  pop         esi
                          0041AC04  xor         eax,eax
                          0041AC06  pop         ebx
                          0041AC07  mov         esp,ebp
                          0041AC09  pop         ebp
                          0041AC0A  ret

                        А вот и результаты (на тысяче итераций инвертирования всех бит):
                        Pentium4 2400 Northwood:
                        ExpandedWrap disabled
                          1000
                          DoFlip time: 1094 ms
                          DoBtc time:  2234 ms

                        Athlon XP 2500+ Barton:
                        ExpandedWrap disabled
                          D:\MyProjects\_TESTS\ConsoleTest3\Release>ConsoleTest3_seq.exe
                          1000
                          DoFlip time: 875 ms
                          DoBtc time:  2250 ms
                        Комментарии в студию!

                        Цитата
                        Ну а теперь всем сразу по поводу приведенных перлов Си.
                        Главное не то как на нем большинство пишет, главное что он позволяет такую чушь писать.

                        Слушай, хватит уже, а? Уже в который раз повторяешь одно и тоже. Ты лучше скажи, почему это позволение так плохо.

                        Знаешь, какие убийства самые распространённые? Отвечу сам - бытовые. А знаешь, какое самое распространённое оружие, используемое при этом? Отвечу сам - обыкновенный кухонный нож. Ты, зная это, призываешь запретить изготовление и свободную продажу этих убийственных вещей, да? И сам их в руки не берешь?

                        По поводу "позволения писать чушь". Мне кажется, что на Форте с его-то гибкостью можно не менее неперевариваемую чушь изобразить. И чего из этого следует?

                        Цитата

                        К.Т.Н. Соловьев А.Е.

                        Потому и кандидат только. :lool: (шутка, не надо это комментировать)
                        Сообщение отредактировано: Hryak -
                          Цитата
                          Т.е. будет ветка с нормальной арифметикой, ветка с длинной, со сверхдлинной и т.д. А результат куда денешь?

                          Достаточно одной операции длинного умножения и деления.
                          Цитата
                          Не знаю, что там актуально для асма (не спец), но для языков высокого уровня бo'льшее значение имеет упорядоченность исходников и простота взаимосвязей кода. И то, и другое будет страдать от подобных фишек.

                          Беда асма - большой объем сорсов. И отчасти поэтому стараешся при любой возможности его уменьшить, вот и получается зачастую лучшая читабельность.
                          Цитата
                          Ничего совершенного не существует. Ляпы оптимизатора - фигня, если язык позволяет писать гораздо быстрее, ненапряжнее и надежнее код, чем ассемблер, а уж существенные ляпы, резко снижающие скорость выполнения критичных участков кода так, что это становится заметно, можно и ручками переписать на том же асме.

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

                          Ага, ты поставил оптимизацию под Pentium Pro (был такой), а пользователь имеет Первопень. Я на себе ощутил, какие его ждут тормоза. Если бы такие тормоза стояли на машинах, то аварий было бы значительно меньше.
                          Цитата
                          Можно сделать несколько версий программы путем простого перекомпилирования с нужными ключами.

                          :lool: То же:
                          Цитата
                          Колонии микробов в плане размножения отдыхают. :lool:

                          Цитата
                          Поэтому я решил накидать маленький тест. Попрошу тебя прокомментировать результаты:

                          Цитата

                          ExpandedWrap disabled
                            0041AAF9 mov dword ptr [esp],ecx
                            0041AAFC lea esp,[esp]
                            0041AB00 mov eax,dword ptr [esp]

                          Без слов.
                          Цитата
                          Комментарии в студию!

                          :lool: :lool: А что ты ожидал увидеть? В первом цикле используется ДВА обращения к памяти, во втором ОДНО. Еще один примерчик хреновой оптимизации. Спасовал С++ перед вставкой из асма, не сумел разобраться, что есть свободные регистры.
                          Впрочем сам тест написан не совсем верно. Во первых тестировать надо в ДОСе (догадываешься почему?). Во вторых я уже сталкивался с ситуацией, когда на результаты очень сильно сказывалось расположение тестируемых подпрограмм (относительно друг друга), последствия кеша. В третьих, GetTickCount() не самый лучший выбор (очень большая погрешность).
                          И в четвертых, вот тебе достоверный тест:
                          ExpandedWrap disabled
                            ; tasm /la /m2 /zi speed.asm
                            ; wlink system dos4g file speed name 0000
                            IDEAL
                            P386
                            MODEL FLAT ,PASCAL
                            SMART
                            LOCALS  __                      ; pазpешаем локальные идентефикатоpы
                            NOJUMPS                         ; запpещаем TASM'у подставлять NOP'ы
                             
                            ITER            = 320000        ; для 320000 полей
                            OVERHEAD        = 17            ; 15 для PPlain, 17 для PMMX
                             
                            MACRO   RDTSC                   ; определяем инструкцию RDTSC
                                    DB      0FH,31H
                            ENDM
                             
                            DATASEG
                              msgResult     db 'Result: ','$'
                              msgCRLF       db ' ticks',13,10,'$'
                            UDATASEG
                              Counter       dd ?            ; счетчик цикла
                              Tics          dd ?            ; временная переменная для значения счетчика
                              ResultList    dd ITER DUP (?) ; список тестовых результатов
                              ResultTics    dd ?            ; результат
                              RandSeed      dd ?
                              BitField      dd (ITER/32) dup (?)
                             
                            STACK 10000h
                             
                            CODESEG
                                    align 4
                            ; получение случайного целого числа
                            PROC _Random NEAR __Range
                                    push    edx
                                    mov     eax,[__Range]
                                    imul    edx,[RandSeed],08088405h
                                    inc     edx
                                    mov     [RandSeed],edx
                                    mul     edx
                                    mov     eax,edx
                                    pop     edx
                                    ret
                            ENDP _Random
                             
                            PROC _Speed
                                    xor     eax,eax
                                    mov     [Counter],eax
                                ; начинаем отсчет
                                    cli                     ; запрещаем прерывания
                                    align 4
                                __loop:
                                    xor     eax,eax         ; очищаем FIFO-буфер инструкций
                                    RDTSC                   ; считываем значение счетчика тактов
                                    mov     [Tics],eax      ; сохраняем его
                                    cld                     ; не спариваемая инструкция
                                    REPT    8
                                    nop                     ;; 8 NOP'ов, чтобы избежать эффекта "затенения"
                                    ENDM
                                ; собственно тестирование
                                    mov     ecx,[Counter]
                            ;---------------------------------------
                                ; 1-я подпрограмка C++
                                    mov     edx,ecx
                                    shr     edx,5
                                    lea     eax,[BitField+edx*4]
                                    and     ecx,1Fh
                                    mov     edx,1
                                    shl     edx,cl
                                    xor     [eax],edx
                                ; 2-я подпрограмка ASM
                            ;        btc     [BitField],ecx
                            ;---------------------------------------
                                ; заканчиваем отсчет
                                    clc                     ; инструкция против спаривания и затенения
                                    RDTSC                   ; снова читаем счетчик
                                    sub     eax,[Tics]      ; вычисляем разность
                                    sub     eax,OVERHEAD    ; вычитаем такты, которые использовали
                                                            ; подсобные инструкции (против спаривания и
                                                            ; затенения)
                                ; сохраняем результат в таблице
                                    mov     edx,[Counter]
                                    mov     [ResultList+edx*4],eax
                                    inc     edx
                                    mov     [Counter],edx
                                    cmp     edx,ITER
                                    jb      __loop          ; повторяем заданное количество раз
                             
                                    sti                     ; разрешаем прерывания
                                ; подсчитываем среднее значение
                                    lea     esi,[ResultList]
                                    mov     ecx,ITER
                                    push    ecx
                                    xor     ebx,ebx
                                    xor     edx,edx
                                __add:
                                    lodsd
                                    add     ebx,eax
                                    adc     edx,0
                                    loop    __add
                                    xchg    eax,ebx
                                    pop     ecx
                                    div     ecx
                                    mov     [ResultTics],eax
                                    ret
                            ENDP _Speed
                             
                            proc _PrintEAX
                                    lea     edi,[esp-4]
                                    sub     esp,16
                                    xor     ebx,ebx
                                    mov     ecx,10
                                    mov     [byte edi],'$'
                                __loop:
                                    xor     edx,edx
                                    div     ecx
                                    dec     edi
                                    add     dl,'0'
                                    mov     [edi],dl
                                    or      eax,eax
                                    jnz     __loop
                                    mov     ah,9
                                    mov     edx,edi
                                    int     21h
                                    add     esp,16
                                    ret
                            endp _PrintEAX
                             
                                    align 4
                            start:
                                    jmp short _main
                                    db 'WATCOM... What me worry?'   ; The "WATCOM" string is needed in
                                                                    ; order to run under DOS/4G and WD.
                            _main:
                                    sti                             ; pазpешаем пpеpывания
                                    cld                             ; сбpасываем флаг напpавления
                                    push    ds
                                    pop     es
                                ; заполняем BitField псевдо случайными значениями
                                    mov     [RandSeed],0fa34a23h    ; гарантия одинакового заполнения
                                    mov     ecx,(ITER/32)
                                    lea     edi,[BitField]
                                fill:
                                    or      eax,-1
                                    call    _Random,eax
                                    stosd
                                    loop    fill
                             
                                    call    _Speed
                                    mov     ah,9
                                    lea     edx,[msgResult]
                                    int     21h
                                    mov     eax,[ResultTics]
                                    call    _PrintEAX
                                    mov     ah,9
                                    lea     edx,[msgCRLF]
                                    int     21h
                                Quit:
                                    push    4C00h                   ; AH=4Ch - Exit To DOS
                                    pop     eax
                                    int 21h                         ; DOS INT 21h
                            ENDS
                            END  Start

                          Результат (Селерон 633):
                          C++ - 34 такта
                          ASM - 33 такта
                          а по размеру счет 7:24 в пользу асма :lol:
                          Вопросы?
                          Сообщение отредактировано: AndNot -
                            Ага. Сразу не заметил - часть времени в DoBtc сжирала пара лишних обращений к памяти.
                            Привел обвязку тестируемого кода в соответствие и замерил время выполнения пустого цикла, которое затем вычел из полученных времён (понятно, что из-за всяческих причин нельзя точно посчитать чистое время выполнения сравниваемых инструкций, но всё-таки...). И время замерил через QueryPerformanceCounter.
                            ExpandedWrap disabled
                              void __fastcall DoFlip(int cnt)
                              {
                                  for (int i = 0; i < cnt; ++i)
                                  {
                                      for (int j = 0; j < nbits; ++j)
                                      {
                                          bs.flip(j);
                                      }
                                  }
                              }
                               
                              __declspec(naked) void __fastcall DoBtc(int cnt)
                              {
                                  __asm
                                  {
                                      push        edi  
                                      mov         edi,ecx
                                      push        ebx  
                                      push        esi  
                                      xor         esi,esi
                                      test        edi,edi
                                      jle         Exit
                                      lea         esp,[esp]
                              OuterLoop:
                                      xor         eax,eax
                                      cmp         eax,493E0h
                              InnerLoop:
                                      jae         OutOfRange
                                      btc         bs,eax
                                      add         eax,1
                                      cmp         eax,493E0h
                                      jl          InnerLoop
                                      add         esi,1
                                      cmp         esi,edi
                                      jl          OuterLoop
                              Exit:
                                      pop         esi  
                                      pop         ebx  
                                      pop         edi  
                                      ret              
                              OutOfRange:
                                      mov         ecx,offset bs
                                      jmp         std::bitset<300000>::_Xran
                                  }
                              }

                            ExpandedWrap disabled
                              DoFlip:
                              00401CE0  push        ecx  
                              00401CE1  push        ebx  
                              00401CE2  push        esi  
                              00401CE3  xor         esi,esi
                              00401CE5  test        edi,edi
                              00401CE7  jle         00401D24
                              00401CE9  lea         esp,[esp+00000000h]
                              00401CF0  xor         eax,eax
                              00401CF2  cmp         eax,493E0h
                              00401CF7  jae         00401D28
                              00401CF9  mov         ecx,eax
                              00401CFB  shr         ecx,5
                              00401CFE  lea         edx,[ecx*4+004237F8h]
                              00401D05  mov         ecx,eax
                              00401D07  and         ecx,1Fh
                              00401D0A  mov         ebx,1
                              00401D0F  shl         ebx,cl
                              00401D11  add         eax,1
                              00401D14  xor         dword ptr [edx],ebx
                              00401D16  cmp         eax,493E0h
                              00401D1B  jl          00401CF7
                              00401D1D  add         esi,1
                              00401D20  cmp         esi,edi
                              00401D22  jl          00401CF0
                              00401D24  pop         esi  
                              00401D25  pop         ebx  
                              00401D26  pop         ecx  
                              00401D27  ret              
                              00401D28  mov         ecx,4237F8h
                              00401D2D  jmp         004024E0
                              .......
                              DoBtc:
                              00401D40  push        edi  
                              00401D41  mov         edi,ecx
                              00401D43  push        ebx  
                              00401D44  push        esi  
                              00401D45  xor         esi,esi
                              00401D47  test        edi,edi
                              00401D49  jle         00401D6F
                              00401D4B  lea         esp,[esp]
                              00401D4E  xor         eax,eax
                              00401D50  cmp         eax,493E0h
                              00401D55  jae         00401D73
                              00401D57  btc         dword ptr ds:[004237F8h],eax
                              00401D5E  add         eax,1
                              00401D61  cmp         eax,493E0h
                              00401D66  jl          00401D55
                              00401D68  add         esi,1
                              00401D6B  cmp         esi,edi
                              00401D6D  jl          00401D4E
                              00401D6F  pop         esi  
                              00401D70  pop         ebx  
                              00401D71  pop         edi  
                              00401D72  ret              
                              00401D73  mov         ecx,4237F8h
                              00401D78  jmp         004024E0

                            Athlon XP 2500+ Barton:
                            ExpandedWrap disabled
                              1000
                              DoEmptyLoop time:  531 ms
                              DoFlip time: all = 890 ms; pure flip = 359 ms
                              DoBtc time: all = 1062 ms; pure btc = 531 ms


                            -Added
                            Цитата AndNot @
                            Цитата
                            Т.е. будет ветка с нормальной арифметикой, ветка с длинной, со сверхдлинной и т.д. А результат куда денешь?

                            Достаточно одной операции длинного умножения и деления.

                            Я не про случай a*b*c/d. Я в общем сказал. Например, a*b*c*d*e/f.

                            Цитата
                            Цитата
                            При компиляции исходника я могу выставить, под какой процессор мне проводить оптимизацию.

                            Ага, ты поставил оптимизацию под Pentium Pro (был такой), а пользователь имеет Первопень. Я на себе ощутил, какие его ждут тормоза.

                            Тоже самое ведь будет, если ты на асме будешь писать под Pentium Pro, а у пользователя окажется Первопень.
                            Да и проверку можно встроить в программу.

                            Цитата
                            :lool: :lool: А что ты ожидал увидеть? В первом цикле используется ДВА обращения к памяти, во втором ОДНО.

                            Да, я уже сам заметил. Поправился.

                            Цитата
                            Результат (Селерон 633):
                            C++ - 34 такта
                            ASM - 33 такта

                            Один такт из 34-х. :)

                            Кстати, еще одна причина проседания btc в моем тесте.
                            Заменил в DoBtc
                            ExpandedWrap disabled
                                      btc         bs,eax
                                      add         eax,1
                                      cmp         eax,493E0h
                            на
                            ExpandedWrap disabled
                                      add         eax,1
                                      btc         bs,eax
                                      cmp         eax,493E0h-1
                            (первый бит перестал инвертироваться, ну да ладно). Стало 406 мс вместо 531. А компилятор это сам прочухал, кстати, когда DoFlip компилял.
                            Сообщение отредактировано: Hryak -
                              Цитата Hryak @
                              и замерил время выполнения пустого цикла,

                              Мог бы и не мучиться, у тебя два цикла, и оба по разным адресам, и с разным выравниванием! Так у тебя будут большие разбросы! Процессоры очень чувствительны к выравниванию.
                              ExpandedWrap disabled
                                DoFlip:
                                [.....]
                                    OuterLoop:
                                00401CF0  xor         eax,eax               ; выровнен на параграф
                                00401CF2  cmp         eax,493E0h
                                    InnerLoop:
                                00401CF7  jae         00401D28              ; не выровнен
                                [.....]
                                00401D14  xor         dword ptr [edx],ebx   ; выровнен на DWORD
                                [.....]
                                 
                                DoBtc:
                                [.....]
                                    OuterLoop:
                                00401D4E  xor         eax,eax                ; выровнен на WORD
                                00401D50  cmp         eax,493E0h
                                    InnerLoop:
                                00401D55  jae         00401D73               ; не выровнен
                                00401D57  btc         dword ptr ds:[004237F8h],eax ; не выровнен
                                [.....]

                              И кстати, я не вижу в этих циклах никакой оптимизации по выравниванию! На каждом InnerLoop сгорает дохрена тактов! А ведь цикл не маленький ;)
                              Цитата Hryak @
                              Я не про случай a*b*c/d. Я в общем сказал. Например, a*b*c*d*e/f

                              И? Что мешает вставить проверку там где необходимо? Это будет лучше чем преобразовывать числа к __int64. Ведь не каждый раз происходит переполнение, и далеко не всегда будет переход на long арифметику.
                              Мне вот встречались конструкции наподобе:
                              ExpandedWrap disabled
                                for (....
                                {
                                  tmp = num;
                                  num += xx[i];
                                  if (num<tmp) Carry++;
                                }
                                  if Carry {...}

                              А ведь все гораздо проще:
                              ExpandedWrap disabled
                                @:
                                  add eax,[ebx]
                                  adc ecx,0
                                  ....
                                  jc __ { }

                              И выглядит попроще, и понятнее. Я уж не говорю за скорость и размер.
                              Цитата Hryak @
                              оже самое ведь будет, если ты на асме будешь писать под Pentium Pro, а у пользователя окажется Первопень.

                              Я никогда не оптимизирую под какой то конкретный проц. Мне хватает самых общих правил, одинаковых для всех процев. Это как правило уже дает неплохие результаты. А оптимизировать желательно FPU! Вот где простор!
                              Цитата Hryak @
                              Да и проверку можно встроить в программу.

                              Зачем плодить лишние ветвления и размер? Есть определенный стиль, пригодный для всех архитектур. Главное выравнивание и размер кода(кэш не резиновый). А вот с этим у ЯВУ напряженка.
                              Цитата Hryak @
                              Один такт из 34-х.

                              На более древних разница будет еще существеннее, но это и не важно. Это всего лишь частный случай, да и про размер не забывай, все таки в 3-и с лишком раза ;)
                              Цитата Hryak @
                              inc eax дольше чем add eax,1 loopnz работает дольше чем sub ecx,1 jnz;

                              loopnz используется несколько иначе ;) И как правило в циклах, где нужна пауза.
                              А вот насчет ADD EAX,1 и INC EAX не уверен, по моим таблицам:
                              Цитата

                              ADD SUB AND OR XOR r , r/i 1 uv
                              INC DEC r 1 uv

                              "А если нет разницы, зачем платить больше"? ©Дося ;)
                                INC/DEC не медленнее ADD/SUB а как раз наоборот.
                                Точнее начиная с Pentium2 одинаково, а на более ранних INC/DEC быстрее.
                                И плюс ко всему при работе с аккумулятором (EAX) занимает меньше места.
                                loop действительно медленне dec/jcc за счёт спаривания.
                                Но опять же для процессоров Intel, на AMD всё совсем наоборот.

                                А вообще тесты такие это всё ерунда потому что очень многое зависит от компилятора.
                                Ты чем компилируешь? Попробуй Intel C Compiler.
                                Хотя ни один компилятор С не обгонит в плане оптимизации нормального программиста на ASM.
                                0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                0 пользователей:
                                Страницы: (31) « Первая ... 16 17 [18] 19 20 ...  30 31


                                Рейтинг@Mail.ru
                                [ Script execution time: 0,1114 ]   [ 15 queries used ]   [ Generated: 19.07.25, 23:53 GMT ]