Войти
ФлеймФорумЖелезо

А если ли у нас ностальгирующие по MOS 6502? (7 стр)

Страницы: 16 7 8 911 Следующая »
#90
10:57, 2 дек. 2017

monobogdan
> Было бы интересно посмотреть тот же код с Hisoft C.

Как он делает понятно после ссылок выше - на паскале уже этот самый код, а ссылка на си с другим кодом есть там же, можно прикинуть что почём. В целом большие прологи и куча перекладываний из регистра в память.
Короче x10 тормозов. А вот у 6502 похоже даже несколько больше.


#91
12:38, 2 дек. 2017

на обычной клавиатуре ПК юзать hisoft c не очень удобно.
Приходится привыкать к функциональным клавишам спектрумовской клавиатуры.
Можно ли где нибудь по нормальной цене взять клон спектрума(можно какой нить Cortex с эмулятором).

#92
12:55, 2 дек. 2017

=A=L=X=
> В общем видно, что всё печально. На порядок медленее, чем полноценный асм.

Ты что такой злой ? Попробуй загнать парсер и простой компилятор в 32 кб :)

#93
13:28, 2 дек. 2017

innuendo
> Попробуй загнать парсер и простой компилятор в 32 кб :)

Большая проблема даже не это, а модель вычислений к которой процессор просто не готов.
Если по ссылкам выше выйти на вот эту тему: http://www.gamedev.ru/flame/forum/?id=155423 , то там явно проговорена одна из причин - адресация на стеке у этих процов как и манипуляции со стеком в целом - ну не очень, особенно у 6502, поэтому надо выносить параметры и переменные со стека для лучшей жизни. Но не очко их там губит, а к реентерабельности стек.
Например тот же CC65 в принципе совершенно без огрех делает a=b+c, при условии что все эти 3 переменных лежат в глобальной памяти - лучше и человек не напишет, там только ухудшить результат можно.

#94
16:47, 2 дек. 2017

Взял теперь из темы ссылка на которую приведена постом выше код который там тестировался на компиляторе Hisoft C вот в этом комментарии: http://www.gamedev.ru/flame/forum/?id=155423&page=3#m32
и протестировал его в CC65.
Речь конкретно о том как отрабатывает банальная реализация strlen когда внутренняя переменная лежит в стеке против того когда она - глобальная переменная (о чём там вся тема). Конкретно код вот такой:

unsigned strlen(s) // взята из lib c со второй стороны кассеты самого Hisoft C
 char *s;
{
 static char *p;
 p=s;
 do ; while(*p++);
 return p-s-1;
}

unsigned strlen2(s) // та же strlen, без static
 char *s;
{
 char *p;
 p=s;
 do ; while(*p++);
 return p-s-1;
}
Асмовыхлоп у CC65 при выбранной платформе "nes" и оптимизации (cc65 -t nes -O test.c) получился следующий (выкинул незначащие вещи):
L0002:
  .res  2,$00

.proc  _strlen: near
  jsr     pushax
  jsr     ldax0sp
  sta     L0002
  stx     L0002+1
L0005:  lda     L0002
  ldx     L0002+1
  sta     regsave
  stx     regsave+1
  jsr     incax1
  sta     L0002
  stx     L0002+1
  ldy     #$00
  lda     (regsave),y
  bne     L0005
  lda     L0002
  sec
  sbc     (sp),y
  pha
  lda     L0002+1
  iny
  sbc     (sp),y
  tax
  pla
  jsr     decax1
  jmp     incsp2
.endproc
.proc  _strlen2: near
  jsr     pushax
  jsr     decsp2
  ldy     #$03
  jsr     ldaxysp
  jsr     stax0sp
L000D:  jsr     ldax0sp
  sta     regsave
  stx     regsave+1
  jsr     incax1
  jsr     stax0sp
  ldy     #$00
  lda     (regsave),y
  bne     L000D
  jsr     ldax0sp
  sec
  ldy     #$02
  sbc     (sp),y
  pha
  txa
  iny
  sbc     (sp),y
  tax
  pla
  jsr     decax1
  jmp     incsp4
.endproc

Вообще как видно в первом коде он действительно завёл переменную в глобальной области и тупо сохраняет/загружает из неё как, например вот здесь во времянку:

L0005:  lda     L0002
  ldx     L0002+1
  sta     regsave
  stx     regsave+1
во втором же случае эта переменная размещена на Си-стеке и потому этот же код превращается в:
L000D:  jsr     ldax0sp
  sta     regsave
  stx     regsave+1
Т.е. прямые загрузки a:x заменяются на вызов подпрограммы по загрузке a:x из стека по смещению 0 и так далее.
Просто для того чтобы понять о чём там идёт речь в этих многочисленных процедурах вот что конкретно эта делает: https://github.com/cc65/cc65/blob/master/libsrc/runtime/ldaxsp.s
ldax0sp:
        ldy     #1
ldaxysp:
        lda     (sp),y          ; get high byte
        tax                     ; and save it
        dey                     ; point to lo byte
        lda     (sp),y          ; load low byte
        rts
Учитывая обилие вызовов аналогичных процедур что в первом что во втором случае тест на спектруме конечно сильно выигрывает особенно в первом случае, потому что во втором как раз происходит вызов тоже какой то обобщённой процедуре *ptr++ почём зря, невзирая на длинные прологи и эпилоги.

#95
16:55, 2 дек. 2017

monobogdan
> вроде как cc65 самый старый из современных компиляторов, я думаю он генерирует
> нормальный код.
Нет, не нормальный, по сравнению с ручным ассемблером не стоит и рядом.

monobogdan
> Мой стиль? Ну он в основном на ООП завязан, даже под C я могу использовать
> классы(структуры + указатель на функцию), хотя под cc65 даже лишний раз функцию
> не нужно вызывать
для сс65 про указатели вообще лучше забыть, кроме совсем уж очевидных мест.

monobogdan
> а на cc65 это отъест либо стек либо регистры а потом будет стек чистить что
> отъест некоторое время).
А если использовать глобалы и статики внутри функций (кстати это один из методов
оптимизации которым пользуется сс65) то вообще чистить ничего не нужно, они все лежат в
одном  постоянном месте. Несмотря на то, что глобалы в теории вообще жуткое зло и прочее
прочее, когда у тебя вариант либо никак, либо через глобалы, то вывод очевиден. ))))

monobogdan
> в юниксах все syscalls используют fastcall, и если 6 аргументов не достаточно
> то передает один из аргументов как структуру.
> Не знаю насколько это жирно в условиях cc65.
Он поддерживает фастколы и, как уже говорилось, через регистр пропихивается только один
аргумент (последний в списке). И никаких структур и указателей.

monobogdan
> Или приходилось записывать в специальный регистр адрес возврата(как в x86).
> Речь о call.

RTS    ---  RTS stands for Return from Subroutine

RTS is one of the 6502 Subroutine Operations of 6502 instruction-set.  The function of RTS is to pulls the
top two bytes off the stack (low byte first) and transfers program control to that address+1 i.e.return (RTS)
from the calling subroutine (6502 JSR instruction).

=A=L=X=
> конкретно на 6502 творится адище с имитацией нехватающих регистров как ячеек в
> zero-page.
а по другому вроде никак.

#96
18:20, 2 дек. 2017

exchg
> для сс65 про указатели вообще лучше забыть, кроме совсем уж очевидных мест.
про указатели на функции или указатели вообще?
Не, ну понятно что там нет какого то API у ОС которое могло бы выделять память и возвращать указатель на него.
Но вроде как сисколлы там это указатели на функции.
exchg
> А если использовать глобалы и статики внутри функций (кстати это один из
> методов
> оптимизации которым пользуется сс65) то вообще чистить ничего не нужно, они все
> лежат в
> одном  постоянном месте. Несмотря на то, что глобалы в теории вообще жуткое зло
> и прочее
> прочее, когда у тебя вариант либо никак, либо через глобалы, то вывод очевиден.
> ))))
Ну учитывая что это 8 бит и там 40кб ОЗУ в худшем случае то согласен)0

#97
19:07, 2 дек. 2017

monobogdan
> про указатели на функции или указатели вообще?
Про оба два. Ну как забыть... Учесть что это относительно дорого. Если
без указателей получается дороже то нужно очевидно использовать
указатели.

monobogdan
> Не, ну понятно что там нет какого то API у ОС которое могло бы выделять память
> и возвращать указатель на него.
Зачем выделать если и так все ОЗУ в твоем распоряжении? ))) Но простой менеджмент
нужен и он реализуется простыми методами например через массивы (по типу обжект
пулов тока статические).

#98
19:22, 2 дек. 2017

exchg
> Учесть что это относительно дорого
Из за математики с CF?

#99
19:47, 2 дек. 2017

monobogdan
> Из за математики с CF?
Наверное из-за того, что указатели 16 бит, а РОН 8 бит и их мало, соответственно
будет постоянный обмен с памятью. Особенно в привычных для десктопов конструкциях
которые уже банально не во что распихать, типа:

void func(type* a, type* b)
{
  a->field0 += b->field0;
  a->field1 += b->field1;
}

Кстати памяти в худшем случае тоже не 48 КБ, а чуть больше 1к.

Плюс относительная слабость оптимизации в сс65. Если бы она была скажем на уровне
GCC то наверное можно было бы закрывать на это глаза и полировать руками в случае
необходимости.

#100
20:06, 2 дек. 2017

exchg
так в zx spectrum же 48кб озу минимум.

#101
20:18, 2 дек. 2017

monobogdan
У минимального спектрума 16 кб озу, но популярность этой модели меркла на фоне 48.

#102
20:18, 2 дек. 2017

monobogdan
> так в zx spectrum же 48кб озу минимум.
а, я говорил за NES.

#103
20:20, 2 дек. 2017

=A=L=X=
exchg
У вас есть чтоли спектрумы? Что вы так за них трясетесь.

#104
20:26, 2 дек. 2017

monobogdan
> Что вы так за них трясетесь.
Всмысле?

Страницы: 16 7 8 911 Следующая »
ФлеймФорумЖелезо