Просьба к...

Разработка программ на пес его знает на чем
Правила форума
При написании вопроса или обсуждении проблемы, не забывайте указывать версию Clarion который Вы используете.
А так же пользуйтесь спец. тегами при вставке исходников!!!
Ответить
Гость

Сообщение Гость »

Здравствуйте

Есть БОЛЬШАЯ просьба к знающим(и имеющим!) C (или C++) и Pascal (любой, кроме Topspeed-овского)
Оттранслируйте пожалуста выражения, эквивалентные кларионовским:

Код: Выделить всё

1.1)
VarLong1 = VarLong1 + VarLong2
1.2)
VarLong1 = VarLong1 / VarLong2
1.3)
VarLong = VarLong1 + VarLong2
1.4)
VarLong = VarLong1 / VarLong2
 
2.1)
VarReal1 = VarReal1 + VarReal2
2.2)
VarReal1 = VarReal1 / VarReal2
2.3)
VarReal = VarReal1 + VarReal2
2.4)
VarReal = VarReal1 / VarReal2
 
3.1)
VarULong1 = VarULong1 - VarULong2
3.2)
VarULong1 = VarULong1 / VarULong2
3.3)
VarULong = VarULong1 - VarULong2
3.4)
VarULong = VarULong1 / VarULong2
 
4.1)
VarLong = VarReal
4.2)
VarReal = VarLong 

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

Очень нужно!
Буду премного благодарен...

Сергей - chusha@mail333.com ; chusha@hotbox.ru

(Добавление)

щас смешную весчь скажу. скомпили то, что ты написал в 1 процедуру, которую помести в кларину dll. hiew-ом стань на начало этой процедуры и сам глянь во что оно оттранслировалось. можешь заглушек между операциями наставить, чтоб виднее было (типа вызова к-нить функции, или некоторой операции a=1).
и пришлите мне ассемблерный код(текст) этого дела.
Только, пожалуйста, с указанием где начало выражения, а где окончание.
а для асма/сей - дык от компилера/платформы зависит. я тебе и так для long-ов это из головы напишу ;) а для лонгов - х.з. у клары там же зачем-то свои классы для работы с ними...


--
Best regards,
Maxim Yemelyanov,
Enigma Soft Company
phone: (057) 7177977
WEB: http://enigmasoft.com.ua
e-mail: clalist@enigmasoft.com.ua
ICQ: 12253836
Написал: ClaList(2)

Гость

Сообщение Гость »

Сщас ещё смешнее скажу. :)
Лучше бы ты скомпилил и прислал мне код, чем писать это.
Тем более ты СИ-шник, насколько мне помниться.
По времени не принципиально больше, а по полезности НАМНОГО.
А теперь прочти ещё раз чего я просил(см.в начале). Особенно два последних слова :/
а для асма/сей - дык от компилера/платформы зависит. я тебе и так для long-ов это из головы напишу ;) а для лонгов - х.з. у клары там же зачем-то свои классы для работы с ними...

Ээээ, у тебя сегодня праздник? Если да, то дальше читай ТОЛЬКО после опохмелки :))
Естественно для Win32, точнее для Intel-подобных процессоров.
И не стоит кивать на клару, я же просил на C.
Кажется там можно написать точно такое же выражение.
Так что нефиг трепаться! :) Компиляй быстрее и шли! Жду...

Сергей - chusha@mail333.com ; chusha@hotbox.ru

лови. если станет легче от результата, сообщи :).
а если серьезно - ну что это за странная такая задача? я не верю в преимущество одного компилируемого языка перед другим при работе со встроенными типами (если не учитывать, что для ULong-ов у клары кажется свой подход).
Так что нефиг трепаться! :) Компиляй быстрее и шли! Жду...
Я не совсем о том. Разные компилеры или опции одного компилера даже на i386 могут давать разные размеры для встроенных типов (8 или 10 для double).

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

Код: Выделить всё

#include <time.h>

int __declspec(dllexport) test()
{
        long l1, l2 = 1;
        unsigned long ul1, ul2 = 1;
        double d1, d2 = 1.00, res;

        time_t t;

        time(&t);
        res = l1+l2;
        time(&t);
        res = l1/l2;
        time(&t);
        res = d1+d2;
        time(&t);
        res = d1/d2;
        time(&t);
        res = ul1+ul2;
        time(&t);
        res = ul1/ul2;
        time(&t);
        l1 = d1;
        time(&t);
        d2 = l2;
        time(&t);
}
----------------------------------------------------

.69701170! 55                       push        ebp
.69701171: 89E5                     mov         ebp,esp
.69701173: 83EC48                   sub         esp,048 ;"H"
.69701176: C745F801000000           mov         d,[ebp][-08],000000001 ;"   ?
.6970117D: C745F001000000           mov         d,[ebp][-10],000000001 ;"   ?
.69701184: D9E8                     fld1
.69701186: DD5DE0                   fstp        q,[ebp][-20]
.69701189: 8D45D4                   lea         eax,[ebp][-2C]
.6970118C: 890424                   mov         [esp],eax
.6970118F: E89C050000               call        time ;msvcrt.dll
.69701194: 8B45F8                   mov         eax,[ebp][-08]
.69701197: 0345FC                   add         eax,[ebp][-04]
.6970119A: 50                       push        eax
.6970119B: DB0424                   fild        d,[esp]
.6970119E: 8D642404                 lea         esp,[esp][04]
.697011A2: DD5DD8                   fstp        q,[ebp][-28]
.697011A5: 8D45D4                   lea         eax,[ebp][-2C]
.697011A8: 890424                   mov         [esp],eax
.697011AB: E880050000               call        time ;msvcrt.dll
.697011B0: 8B55FC                   mov         edx,[ebp][-04]
.697011B3: 8D45F8                   lea         eax,[ebp][-08]
.697011B6: 8945CC                   mov         [ebp][-34],eax
.697011B9: 89D0                     mov         eax,edx
.697011BB: 8B4DCC                   mov         ecx,[ebp][-34]
.697011BE: 99                       cdq
.697011BF: F739                     idiv        d,[ecx]
.697011C1: 8945CC                   mov         [ebp][-34],eax
.697011C4: DB45CC                   fild        d,[ebp][-34]
.697011C7: DD5DD8                   fstp        q,[ebp][-28]
.697011CA: 8D45D4                   lea         eax,[ebp][-2C]
.697011CD: 890424                   mov         [esp],eax
.697011D0: E85B050000               call        time ;msvcrt.dll
.697011D5: DD45E8                   fld         q,[ebp][-18]
.697011D8: DC45E0                   fadd        q,[ebp][-20]
.697011DB: DD5DD8                   fstp        q,[ebp][-28]
.697011DE: 8D45D4                   lea         eax,[ebp][-2C]
.697011E1: 890424                   mov         [esp],eax
.697011E4: E847050000               call        time ;msvcrt.dll
.697011E9: DD45E8                   fld         q,[ebp][-18]
.697011EC: DC75E0                   fdiv        q,[ebp][-20]
.697011EF: DD5DD8                   fstp        q,[ebp][-28]
.697011F2: 8D45D4                   lea         eax,[ebp][-2C]
.697011F5: 890424                   mov         [esp],eax
.697011F8: E833050000               call        time ;msvcrt.dll
.697011FD: 8B45F0                   mov         eax,[ebp][-10]
.69701200: 0345F4                   add         eax,[ebp][-0C]
.69701203: BA00000000               mov         edx,000000000 ;"    "
.69701208: 52                       push        edx
.69701209: 50                       push        eax
.6970120A: DF2C24                   fild        q,[esp]
.6970120D: 8D642408                 lea         esp,[esp][08]
.69701211: DD5DD8                   fstp        q,[ebp][-28]
.69701214: 8D45D4                   lea         eax,[ebp][-2C]
.69701217: 890424                   mov         [esp],eax
.6970121A: E811050000               call        time ;msvcrt.dll
.6970121F: 8B55F4                   mov         edx,[ebp][-0C]
.69701222: 8D45F0                   lea         eax,[ebp][-10]
.69701225: 8945CC                   mov         [ebp][-34],eax
.69701228: 89D0                     mov         eax,edx
.6970122A: 8B4DCC                   mov         ecx,[ebp][-34]
.6970122D: BA00000000               mov         edx,000000000 ;"    "
.69701232: F731                     div         d,[ecx]
.69701234: 8945CC                   mov         [ebp][-34],eax
.69701237: 8B45CC                   mov         eax,[ebp][-34]
.6970123A: BA00000000               mov         edx,000000000 ;"    "
.6970123F: 52                       push        edx
.69701240: 50                       push        eax
.69701241: DF2C24                   fild        q,[esp]
.69701244: 8D642408                 lea         esp,[esp][08]
.69701248: DD5DD8                   fstp        q,[ebp][-28]
.6970124B: 8D45D4                   lea         eax,[ebp][-2C]
.6970124E: 890424                   mov         [esp],eax
.69701251: E8DA040000               call        time ;msvcrt.dll
.69701256: DD45E8                   fld         q,[ebp][-18]
.69701259: D97DD2                   fstcw       [ebp][-2E]
.6970125C: 0FB745D2                 movzx       eax,w,[ebp][-2E]
.69701260: 660D000C                 or          ax,00C00 ;"? "
.69701264: 668945D0                 mov         [ebp][-30],ax
.69701268: D96DD0                   fldcw       [ebp][-30]
.6970126B: DB5DFC                   fistp       d,[ebp][-04]
.6970126E: D96DD2                   fldcw       [ebp][-2E]
.69701271: 8D45D4                   lea         eax,[ebp][-2C]
.69701274: 890424                   mov         [esp],eax
.69701277: E8B4040000               call        time ;msvcrt.dll
.6970127C: DB45F8                   fild        d,[ebp][-08]
.6970127F: DD5DE0                   fstp        q,[ebp][-20]
.69701282: 8D45D4                   lea         eax,[ebp][-2C]
.69701285: 890424                   mov         [esp],eax
.69701288: E8A3040000               call        time ;msvcrt.dll
.6970128D: C9                       leave
.6970128E: C3                       retn
--
Best regards,
Maxim Yemelyanov
лови. если станет легче от результата, сообщи :).
Легче не стало :( Код почти такой же.
И не понятно почему он ТАК медленно работает! :(
На моей машине операция
long=real
даёт порядка 3 млн. оп/сек
а по прикидкам на пальцах должно давать порядка 60.
Вот если бы ты потестировал сколько присвоений типа l1 = d1
в секунду дает твой компилер, было бы здорово!
Кстати, а что за язык(компилер) ты использовал?
а если серьезно - ну что это за странная такая задача? я не верю в преимущество одного компилируемого языка перед другим при работе со встроенными типами (если не учитывать, что для ULong-ов у клары кажется свой подход).

Может ты и прав...
Я не совсем о том. Разные компилеры или опции одного компилера даже на i386 могут давать разные размеры для встроенных типов (8 или 10 для double).
В кларионе 8-ми байтное.
Насколько я понял использовать 10-и байтное не есть хорошо, т.к.
придётся самому "гарантировать" отсутствие потерь при арифм.операциях.
При 8-ми байтных вещественных потери минимизируются за счет
10-и байтного представления вещ.чисел в сопроцессоре.

Сергей
Написал: ClaList(2)

Гость

Сообщение Гость »

[Q] Легче не стало :( Код почти такой же.[/quote]
А ты ждал чудес?
И не понятно почему он ТАК медленно работает! :(
А почему ты считаешь, что это медленно?
На моей машине операция
long=real
даёт порядка 3 млн. оп/сек
а по прикидкам на пальцах должно давать порядка 60.
По каким таким прикидкам?
Вот если бы ты потестировал сколько присвоений типа l1 = d1
в секунду дает твой компилер, было бы здорово!
Кстати, а что за язык(компилер) ты использовал?
1. gcc version 3.3.1 (mingw special 20030804-1)
2. Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8168 for 80x86

gcc:
1. time taken: 32.453000, approx. speed is 66.172115 MOps/sec
2. time taken: 6.484000, approx. speed is 331.197355 MOps/sec

vc:
1. time taken: 43.266000, approx. speed is 49.634439 MOps/sec
2. time taken: 6.484000, approx. speed is 331.197355 MOps/sec

CPU: Cel 2Gz

код:

Код: Выделить всё

#include <windows.h>

int main()
{
    double d=1234.5678, d1=123, d2;
    long l;
    unsigned long i, retries=0x7FFFffff;

    long t0, t1;

    t0 = GetTickCount();

    for(i=0;i<retries;i++)
    {
        l = d;
    }

    t1 = GetTickCount();
    printf("1. time taken: %.6f, approx. speed is %.6f MOps/sec \n", (double)(t1-t0)/1000, (double)retries/(t1-t0)/1000 );

    t0 = GetTickCount();

    for(i=0;i<retries;i++)
    {
        d2 = d * d1;
    }

    t1 = GetTickCount();
    printf("2. time taken: %.6f, approx. speed is %.6f MOps/sec \n", (double)(t1-t0)/1000, (double)retries/(t1-t0)/1000 );
}
Машинный код ты видел. Дальше сам смотри. Затраты в кларе на вызов функции могут оказаться намного большими, чем то, что есть у тебя сейчас. Другое дело, что ты свои алгоритмы целиком можешь вынести наружу и реализовать их хоть на асме, что может дать ускорение. Может твое мнение об оптимизации данной ветки кода будет отличаться от компилерской. Тем более, что ты как автор, можешь делать предположения о входных данных, и оптимизировать те ветки, которые будут использоваться чаще.

--
Best regards,
Maxim Yemelyanov
Написал: ClaList(2)

Гость

Сообщение Гость »

А ты ждал чудес?

Хотел понять - почему?
По каким таким прикидкам?

По тактам на каждую машинную операцию. В кларе это 41 такт.
В принципе по тактам удобно считать, в большинстве случаев расчеты близки к практическим результатам. А вот то "меньшинство", как например это операция, плевали на эти такты!
gcc:
1. time taken: 32.453000, approx. speed is 66.172115 MOps/sec
2. time taken: 6.484000, approx. speed is 331.197355 MOps/sec

vc:
1. time taken: 43.266000, approx. speed is 49.634439 MOps/sec
2. time taken: 6.484000, approx. speed is 331.197355 MOps/sec

О чём я и говорил! В 20 раз быстрее! Этого мне бы хватило.
Если не трудно, пришли мне АСМ-код этих двух циклов - поглазею ещё :)
Тем более, непонятно почему здесь тоже есть разница. Наверное код разный.
Кстати, хошь ещё тестик?
Модифицируй свой код примерно так
(эквивалент real1=real1*real2)

Код: Выделить всё

 t1 = GetTickCount();
    printf("1. time taken: %.6f, approx. speed is %.6f MOps/sec \n", (double)(t1-t0)/1000, (double)retries/(t1-t0)/1000 );

    t0 = GetTickCount();

    for(i=0;i<retries;i++)
    {
        d1 = d1 * d;
    }

    t1 = GetTickCount();
    printf("2. time taken: %.6f, approx. speed is %.6f MOps/sec \n", (double)(t1-t0)/1000, (double)retries/(t1-t0)/1000 );
}
И каков теперь результат? :)
В кларе те же самые 2.5 млн.оп/сек :(
Но если записать так
d1 = d2 * d
даёт 1000 млн.оп/сек
Хошь стой, хошь падай как говориться...
Затраты в кларе на вызов функции могут оказаться намного большими, чем то, что есть у тебя сейчас.

А при чём тут функции? Всё в цикле, как у тебя.
Т.е. меня интересует только конкретное присваивание.
Другое дело, что ты свои алгоритмы целиком можешь вынести наружу и реализовать их хоть на асме, что может дать ускорение.

Хм, а я так и не понял, как подключать АСМ к кларе. :(
В смысле компилится всё нормально, а вот как заставить это работать - непонятки. Примерчик нужен или внятное объяснение.
Может твое мнение об оптимизации данной ветки кода будет отличаться от компилерской. Тем более, что ты как автор, можешь делать предположения о входных данных, и оптимизировать те ветки, которые будут использоваться чаще.

Неее, так глубоко я не лезу. Хотя и перечитал всё что можно найти в инете по поводу оптимизации кода, но конкретных предложений как сделать быстро целое=вещ. так и не нашёл :(

Сергей
Написал: ClaList(2)

Гость

Сообщение Гость »

А ты ждал чудес?
Хотел понять - почему? :)
для этого изучай асмовый листинг.
По тактам на каждую машинную операцию. В кларе это 41 такт.
Точно? Ты точно уверен что на P4 эта операция занимает столько-то тактов, на P2 - столько-то, а на атлоне - вот столько?
Модифицируй свой код примерно так (эквивалент real1=real1*real2)
Мы - толпа придурков из 2-х человек :)
Всё очень просто:

d2 = d1 * d; -- первый цикл
d1 = d1 * d; -- второй

1. time taken: 11.086000, approx. speed is 193.711316 MOps/sec
2. time taken: 204.975000, approx. speed is 10.476808 MOps/sec

Щас глупость спрошу: у сопроцессора есть кеш?
В первом случае идет умножение 2-х констант, которые а) могут осесть в кеше сопроцессора и б) не так уж сложны, чтобы сопр их быстренько умножил.
Во 2-м случае идет постоянное изменение 2-го множителя, что может давать большее чем для 1-го случая время умножения.
Дико стыдно, что не знаю особенностей архитектуры процов после 386-го, может кто раскритикует предположение?
То есть, может ли fmul отработать быстрее, чем ее максимальное время, или эта и все другие операции занимают константное число тактов сопра невзирая на операнды?
Хм, а я так и не понял, как подключать АСМ к кларе. :(
В смысле компилится всё нормально, а вот как заставить это работать - непонятки. Примерчик нужен или внятное объяснение.
Я имел в виду - написать библиотеку нужных алгоритмов на чем-то кроме клары, если уж хочется экспериментов. И линковать ее к проекту.
Неее, так глубоко я не лезу. Хотя и перечитал всё что можно найти в инете по поводу оптимизации кода, но конкретных предложений как сделать быстро целое=вещ. так и не нашёл :(
Я не о том. Я о том, что ты: а) знаешь свой код и б) предполагаешь, _какие_
именно данные _чаще_ всего будут поступать на вход твоему алгоритму. И,
соответственно, сможешь оптимизировать алгоритм (на уровне логики) так, чтобы в _большинстве_ случаев он давал выигрыш по сравнению с изначальным вариантом.

--
Best regards,
Maxim Yemelyanov

(Добавление)
Точно? Ты точно уверен что на P4 эта операция занимает столько-то тактов, на P2 - столько-то, а на атлоне - вот столько?

У меня П-4. Другие операции, например real=long, почти точно соответствуют расчёту. Такты считал по таблице для П-3. Для П-4 не нашёл так запросто.
Предполагаю, что если и будет расхождение, то в лучшую сторону. :)
Если не трудно, пришли мне АСМ-код этих двух циклов - поглазею ещё :)

Как насчет кода?
Мы - толпа придурков из 2-х человек :)

Хм, навеяло: "На груди его могучей три волоска толпились кучей"
1. time taken: 11.086000, approx. speed is 193.711316 MOps/sec
2. time taken: 204.975000, approx. speed is 10.476808 MOps/sec

О! И я о том же! А почему? Кто б просвятил...
Кстати, а чегой-то у тебя цифры резко вниз пошли?
Вроде было 331, а теперь 193?
Щас глупость спрошу: у сопроцессора есть кеш?

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

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

А ему до лампочки какие перемножать :)
Внутри он всегда работает с вещ. расширенного типа (80 бит).
Во 2-м случае идет постоянное изменение 2-го множителя, что может давать большее чем для 1-го случая время умножения.

Не-а. Код (по крайней мере в кларе!) абсолютно один и тот же, кроме адресации памяти.
То есть, может ли fmul отработать быстрее, чем ее максимальное время, или эта и все другие операции занимают константное число тактов сопра невзирая на операнды?

В данном случае неважно. Т.к. если машинные операции могут (а некоторые могут) перекрываться другой операцией, то это только убыстрит время работы (за счет параллельного выполнения) от простого расчёта по тактам.
Я имел в виду - написать библиотеку нужных алгоритмов на чем-то кроме клары, если уж хочется экспериментов. И линковать ее к проекту.

А я о чём? Ну написал я что-то на АСМе, а дальше что? Как это дело использовать в кларе?
И, соответственно, сможешь оптимизировать алгоритм (на уровне логики) так, чтобы в _большинстве_ случаев он давал выигрыш по сравнению с изначальным вариантом.

Свой код я знаю. И оптимизирую в меру сил и возможностей.
Но иногда упираешься в то, что не в моей власти. Как в данном случае.

Сергей
А я о чём? Ну написал я что-то на АСМе, а дальше что?
Как это дело использовать в кларе?
Да очень просто!
Пишешь исходник на ASM-е, даешь ему расширение .A
Болванка исходника:

Код: Выделить всё

module  MyAsmLib      (* Начало модуля *)

segment SUPPORT_TEXT(CODE,48H)

(* ----------------- *)
public  MyFunc1:      (* Обьявление процедуры *)
(* ----------------- *)

ret     near 0        (* Конец процедуры MyFunc1 *)

end                   (* Конец модуля *)

Только сразу предупреждаю - у Клары несколько свое,
отличное от стандарта, понимание ASM-кода!
Так что - прийдется много ручками адаптировать.
А некоторые операторы вообще записывать прямо в виде кода!
К примеру, простенькая процедура сохранения текущих
значений регистров:

(* ---------------------------------------------- *)
public  SaveRegs:   (* (LONG _AddrSaveArray),LONG *)
(* ---------------------------------------------- *)
  cmp   ax,0
  je    DoRet

  push  di
  mov   di,ax
  pop   ax

  dw    01F89H               (* mov [edi],ebx *)
  add   di,4
  dw    00F89H               (* mov [edi],ecx *)
  add   di,4
  dw    01789H               (* mov [edi],edx *)
  add   di,4
  dw    03789H               (* mov [edi],esi *)
  add   di,4
  dw    00789H               (* mov [edi],eax *)

  push  di
  mov   di,ax
  pop   ax

DoRet:
  ret   near 0
На Кларионе эта процедура обьявляется просто:

Код: Выделить всё

   MAP
     SaveRegs(STRING _Regs),LONG,PROC,RAW,NAME('SaveRegs')
   END
Кстати, если заметил, вместо EAX и т.д. Клара понимает только обычную форму AX/BX...

После написания A-модуля цепляешь его в проект к нужной проге и в MAP-секции прописываешь нужные прототипы. И все!

Как видишь - проблем практически никаких!
Основная проблема - правильно написать сам ASM-код так, что-бы Кларин компилятор его смог обработать!

=============================
С уважением, Олег А. Руденко.
Oleg_Rudenko@mail.ru
Oleg_Rudenko@mail333.com
Библиотека DynaLib
http://dynalib.narod.ru
Написал: ClaList(2)

Ответить