Важная информация

User Tag List

Страница 1 из 6 12345 ... ПоследняяПоследняя
Показано с 1 по 10 из 53

Тема: к вопросу о разумности использования компиляторов C на спеке

  1. #1
    Sinclair User Аватар для Eltaron
    Регистрация
    16.01.2005
    Адрес
    Ekaterinburg
    Сообщений
    2,045
    Записей в дневнике
    7
    Спасибо Благодарностей отдано 
    143
    Спасибо Благодарностей получено 
    463
    Поблагодарили
    326 сообщений
    Mentioned
    4 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию к вопросу о разумности использования компиляторов C на спеке

    давно занимает эта тема
    вот, решил потестировать все компиляторы, до которых дотянулись руки
    проверял на банальнейшей штуке - заливке всего экрана черным цветом, вот такой вот код:
    Код:
    int main()
    {
      unsigned char* t;
      t = 16384;
      while (t<16384+6144)
      {
        *t = 255;
        t++;
      }
      return 0;
    }
    специально не использовал никаких библиотек, если что, их всегда можно написать самому, да и не нужна на спеке добрая половина их возможностей.
    первым попался под руку z88dk
    вот что он мне выдал
    Код:
    ._main
    	ld	hl,16384	;const
    	push	hl
    .i_3
    	pop	hl
    	push	hl
    	ld	de,22528	;const
    	ex	de,hl
    	call	l_ult
    	jp	nc,i_4
    	pop	hl
    	push	hl
    	ld	(hl),#(255 % 256 % 256)
    	pop	hl
    	inc	hl
    	push	hl
    	dec	hl
    	jp	i_3
    .i_4
    	ld	hl,0	;const
    	pop	bc
    	ret
    то есть даже в таком примитивном коде наворочено по максимуму
    причем, это только асмовый исходник, после линковки он добавляет еще мусора
    пытаться скомпилировать этот код руками не стал, нервы дороже
    в общем, барахло, а не компилятор

    Дальше был sdcc
    им уже вполне можно пользоваться, судите сами:
    Код:
    	org #9c40
    _main_start::
    _main:
    	ld	bc,#4000
    _l00101: 
    	ld	e,c
    	ld	d,b
    	ld	a,e
    	sub	a,#00
    	ld	a,d
    	sbc	a,#58
    	jp	p, _l00103
    	ld	a,#FF
    	ld	(bc),a
    	inc	bc
    	jp	 _l00101
    _l00103: 
    	ld	hl,#0000
    _l00104: 
    	ret
    слишком много явно лишних операций(типа вычитания нуля из аккумулятора), но это уже что-то
    но хотелось лучшего и я полез в инет
    нашел еще компилятор от Softools, но он слишком хотел денег и у меня запуститься отказался наотрез
    и, в конце-концов наткнулся на компилятор от IAR. Плох он тем, что нет command-line утилит, все встроено в IDE, и писать приходится в нем, неудобно, все же FAR роднее
    вот такое вот чудо он нагенерировал:
    Код:
    	org #9c40
    main:
            PUSH    BC
            PUSH    IX
            LD      IX,0
            ADD     IX,SP
            PUSH    AF
            LD      (IX-2),0
            LD      (IX-1),64
    l0001:
            LD      BC,22528
            LD      L,(IX-2)
            LD      H,(IX-1)
            AND     A
            SBC     HL,BC
            JR      NC,l0000
    l0002:
            LD      L,(IX-2)
            LD      H,(IX-1)
            LD      (HL),255
            INC     (IX-2)
            JR      NZ,l0003
            INC     (IX-1)
    l0003:
            JR      l0001
    l0000:
            LD      SP,IX
            POP     IX
            POP     BC
            RET
    оно, конечно, работает, но не радует, блин
    и тут меня как ударило - что-то слишком активно с памятью он работает, и я полез искать в опциях настройки компиляции
    и вот оно! оптимизация - Default/Size/Speed
    ну, поставил Speed на максимум
    вот что выдал:
    Код:
    	org #9c40
    main:
            PUSH    BC
            PUSH    DE
            LD      DE,16384
    l0001:
            LD      BC,22528
            LD      H,D
            LD      L,E
            AND     A
            SBC     HL,BC
            JR      NC,l0000
    l0002:
            LD      H,D
            LD      L,E
            LD      (HL),255
            INC     DE
            JR      l0001
    l0000:
            POP     DE
            POP     BC
            RET
    довольно непривычно глазу(я б не так написал :-)), но работает
    а, главное, действительно оптимизировано, лень такты подсчитывать, но, думаю, это самый быстрый вариант

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

    ЗЫ везде из сгенеренного компилером кода вычищен весь мусор и сам код переделан для нормального ассемблирования сторонним спектрумским ассемблером(я юзал sjasm)
    Граф Дракула наш кумир, патамушта он вомпир!
    VKINK 9 : BORDER NOT PI

  2. #1
    С любовью к вам, Yandex.Direct
    Размещение рекламы на форуме способствует его дальнейшему развитию

  3. #2
    Veteran Аватар для lvd
    Регистрация
    23.01.2005
    Сообщений
    1,113
    Спасибо Благодарностей отдано 
    0
    Спасибо Благодарностей получено 
    3
    Поблагодарили
    3 сообщений
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Цитата Сообщение от Eltaron
    Дальше был sdcc
    ld a,e
    sub a,#00
    ld a,d
    sbc a,#58
    jp p, _l00103
    Ошибка. Должно быть jp c/nc, потому что #ff00 -#5800 - будет флаг N стоять.

    довольно непривычно глазу(я б не так написал :-)), но работает
    а, главное, действительно оптимизировано, лень такты подсчитывать, но, думаю, это самый быстрый вариант
    Посчитай и убедись, что сдцц всё же в данном случае дал наиболее оптимальный код - без коматозных 16-битных конструкций и тд. Вот ещё бы и правильный был бы =)
    --- Кто съел всю уху?

  4. #3
    Guru Аватар для breeze
    Регистрация
    11.02.2005
    Адрес
    【RB】
    Сообщений
    3,692
    Спасибо Благодарностей отдано 
    29
    Спасибо Благодарностей получено 
    42
    Поблагодарили
    30 сообщений
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)

    Question

    Цитата Сообщение от Eltaron
    если кто заинтересовался - компилер можно бесплатно скачать с www.iar.com(4 мега). Там написано, что это демо-версия, но никаких ограничений пока не заметил
    это этот линк ? http://supp.iar.com/FilesPublic/EWDE...560/ewz80d.zip
    (๑•̀ㅂ•́)و✧ Doors UI → https://t.me/doorsui | https://t.me/atari_xl_xe ← Atari XL/XE (●´ω`●)ゞ

  5. #4
    Sinclair User Аватар для Eltaron
    Регистрация
    16.01.2005
    Адрес
    Ekaterinburg
    Сообщений
    2,045
    Записей в дневнике
    7
    Спасибо Благодарностей отдано 
    143
    Спасибо Благодарностей получено 
    463
    Поблагодарили
    326 сообщений
    Mentioned
    4 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Цитата Сообщение от breeze
    он самый

    Посчитай и убедись, что сдцц всё же в данном случае дал наиболее оптимальный код - без коматозных 16-битных конструкций и тд. Вот ещё бы и правильный был бы =)
    ну не знаю, один коматозный sbc идет 15 тактов, а у sdcc два некоматозных, но по 7, почти то же самое
    но эт я так, навскидку, внимательно потом посчитаю
    Граф Дракула наш кумир, патамушта он вомпир!
    VKINK 9 : BORDER NOT PI

  6. #5
    Sinclair User Аватар для Eltaron
    Регистрация
    16.01.2005
    Адрес
    Ekaterinburg
    Сообщений
    2,045
    Записей в дневнике
    7
    Спасибо Благодарностей отдано 
    143
    Спасибо Благодарностей получено 
    463
    Поблагодарили
    326 сообщений
    Mentioned
    4 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    ладно, соглашусь, что если бы sdcc не делал ошибок и умел бы выкидывать ненужные инструкции, то цены бы ему не было :-))
    но это в том примере
    а счас для сравнения вот такое:
    main.c:
    Код:
    #include "main.h"
    
    void main(void)
    {
      gotoXY(10,10);
      printf("Hello, world!");
    }
    main.h:
    Код:
    void gotoXY(char x, char y);
    void printf(char* data);
    естественно, линковщик будет ругаться, ибо тел продекларированных функций нет, но черт с ним, с линковщиком, все равно у него на выходе что-то непотребное, проще обычным ассемблером ассемблировать

    вот sdcc:
    Код:
    _main_start::
    _main:
    	ld	hl,#0x0A0A
    	push	hl
    	call	_gotoXY
    	pop	af
    	ld	hl,#__str_0
    	push	hl
    	call	_printf
    	pop	af
    00101$:
    	ret
    _main_end::
    __str_0:
    	.ascii "Hello, world!"
    а вот iar ewz80:
    Код:
    main:
            PUSH    BC
            PUSH    DE
            LD      C,10
            LD      E,C
            CALL    gotoXY
            LD      DE,?0000   ; вот это место мне не нравится, к божескому виду приводится только встроенным линкером
            CALL    printf
            POP     DE
            POP     BC
            RET
    комментарии, думаю, излишни
    один ld e,c чего стоит
    да и sdcc передает аргументы через стек, как принято на pc, а iar если аргументов мало, заполняет ими регистры
    еще sdcc чуть что, начинает воротить огород вокруг индексных регистров, ewz80 тоже, но реже и код у него выглядит лучше(может, конечно, работает хуже , не тестировал)
    в общем, мне определенно нравится iar'овский компайлер
    но нашел у него большую проблему - он не вставляет в ассемблерный листинг строковые(а может и не только) константы, счас думаю, как это обходить...
    Граф Дракула наш кумир, патамушта он вомпир!
    VKINK 9 : BORDER NOT PI

  7. #6
    Veteran Аватар для lvd
    Регистрация
    23.01.2005
    Сообщений
    1,113
    Спасибо Благодарностей отдано 
    0
    Спасибо Благодарностей получено 
    3
    Поблагодарили
    3 сообщений
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Цитата Сообщение от Eltaron
    комментарии, думаю, излишни
    один ld e,c чего стоит :)
    да и sdcc передает аргументы через стек, как принято на pc, а iar если аргументов мало, заполняет ими регистры
    еще sdcc чуть что, начинает воротить огород вокруг индексных регистров, ewz80 тоже, но реже и код у него выглядит лучше(может, конечно, работает хуже :), не тестировал)
    в общем, мне определенно нравится iar'овский компайлер :)
    но нашел у него большую проблему - он не вставляет в ассемблерный листинг строковые(а может и не только) константы, счас думаю, как это обходить...
    Одним словом, любой компюлер цэ для з80 можно заставить бред нагенерить. О чём и речь - на з80 нормально можно только на асме прогать. Ни один компайлер не догадается на for(i=0;i<256;i++) a[i]=0; нагенерить ld sp,:ld de,0:push de:push de:...:push de. А кодер в маинлупе или в инте где критично время исполнения - такое автоматом влепит.
    --- Кто съел всю уху?

  8. #7
    Activist Аватар для Raider
    Регистрация
    24.06.2005
    Адрес
    novosibirsk
    Сообщений
    266
    Записей в дневнике
    5
    Спасибо Благодарностей отдано 
    0
    Спасибо Благодарностей получено 
    1
    Поблагодарили
    1 сообщение
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Отпишу мысли..

    Цитата Сообщение от Eltaron
    давно занимает эта тема
    вот, решил потестировать все компиляторы, до которых дотянулись руки
    проверял на банальнейшей штуке - заливке всего экрана черным цветом, вот такой вот код:
    Код:
    int main()
    {
      unsigned char* t;
      t = 16384;
      while (t<16384+6144)
      {
        *t = 255;
        t++;
      }
      return 0;
    }

    Еще есть некий Avocet compiler - доступен в edonkey network (правда лучше пользовать emule клиента).

    Еще есть GCC. И к нему есть патч (текстовая заплатка на исходники чтобы получить кодогенерацию для z80).

    Еще должны быть ссылки на сайте Zilog (если zilog еще живой, не был там лет 5-6 уже наверное).


    Ты неправильно сделал то что поместил пример прямо внутрь int main()
    это чревато. Всегда тестируй в отдельной функции:

    Код:
    void test() {
    
    }
    main - системный вход и мало ли что туда может попадать. Непредсказуемо
    туда по-идее должна попадать argc и argv и возвращаться результат.


    хорошо, если компилятор додумается посчитать инвариантные константы. в (t<16384+6144) Но он не обязан.

    Указатели в любом компиляторе оптимизируются плохо, и лучше всего их заменять адресацией t[x] - может выйти эффективнее.

    Указатель t - 16-битный. А это форсирует компилятор применять 16-битную арифметику, т.к. ты ему написал операцию сравнения (t<16384+6144) которые явно 16-битные, так что эффективного кода для z80 не жди. Эффективнее может оказаться следущее:

    Код:
    unsigned char *t = 0x4000;
    register i; // или unsigned short
    
    for(i=0x1800; i != 0; i--)  *t++ = (unsigned char)0xFF;
    А вообще, должно было быть
    Код:
    memset( 0x4000, 0x00, 0x1800)
    - компилятор должен позвать либо библиотечную функцию, либо заменить ее на встроенный intrinsic в виде LDIR'а.

    Мое мнение - писать на компайлерах наверное можно, но нужно четко понимать что за чем стоит там внутри. В основном, писать логику программы, и из нее дергать функции на асме.

    p.s.
    Из компиляторов самый перспективный будет GCC (в теории), особенно, если довести его кодогенерацию для z80 до ума. Вполне вероятно, что какая-то из фирм так и сделала, это обычный путь, пройденый уже не раз.
    Alex Raider, Flash inc. 1992-1997 Новосибирск

  9. #8
    Sinclair User Аватар для Eltaron
    Регистрация
    16.01.2005
    Адрес
    Ekaterinburg
    Сообщений
    2,045
    Записей в дневнике
    7
    Спасибо Благодарностей отдано 
    143
    Спасибо Благодарностей получено 
    463
    Поблагодарили
    326 сообщений
    Mentioned
    4 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Цитата Сообщение от Raider
    main - системный вход и мало ли что туда может попадать. Непредсказуемо
    я и не смотрел на код до и после моего цикла
    а внутри него никаких последствий от main'а быть уже не должно
    туда по-идее должна попадать argc и argv и возвращаться результат.
    ну, это понятно, не первый раз замужем :-)
    просто плох тот компилятор, который при отсутствии argv и argc будет городить код для их обработки, а компайлер, не могущий посчитать константу вообще можно сразу на свалку

    Цитата Сообщение от Raider
    т.к. ты ему написал операцию сравнения (t<16384+6144) которые явно 16-битные
    это да, конечно же надо цикл обратно к нулю крутить, но я же не задавался мыслью написать оптимально, чтоб компилер выдал красотищу, я писал примитив и смотрел, что скажут разные компилеры

    а gcc для z80 - это очень интересно, надо поискать... Avocet поставил на закачку, качнется, потестю
    Граф Дракула наш кумир, патамушта он вомпир!
    VKINK 9 : BORDER NOT PI

  10. #9
    Guru Аватар для jerri
    Регистрация
    01.03.2005
    Адрес
    Samara
    Сообщений
    4,751
    Спасибо Благодарностей отдано 
    256
    Спасибо Благодарностей получено 
    266
    Поблагодарили
    200 сообщений
    Mentioned
    12 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Я бы рекомендовaл пoсмотреть изнутри игрушку Mr Whimpy & Shi Vampires

    Очень интересный результат применения компиляторов
    С уважением,
    Jerri / Red Triangle.

  11. #10
    Master Аватар для key-jee
    Регистрация
    16.01.2005
    Адрес
    Пермь
    Сообщений
    514
    Спасибо Благодарностей отдано 
    0
    Спасибо Благодарностей получено 
    1
    Поблагодарили
    1 сообщение
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Thumbs up

    Цитата Сообщение от Raider
    Мое мнение - писать на компайлерах наверное можно, но нужно четко понимать что за чем стоит там внутри. В основном, писать логику программы, и из нее дергать функции на асме.
    Золотые слова..
    Последний раз редактировалось key-jee; 13.09.2005 в 05:00.

Страница 1 из 6 12345 ... ПоследняяПоследняя

Информация о теме

Пользователи, просматривающие эту тему

Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •