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

User Tag List

Страница 2 из 7 ПерваяПервая 123456 ... ПоследняяПоследняя
Показано с 11 по 20 из 70

Тема: sPycialist - эмулятор ПК Специалист на Python

  1. #11
    Administrator Аватар для CityAceE
    Регистрация
    13.01.2005
    Адрес
    г. Москва
    Сообщений
    4,575
    Записей в дневнике
    7
    Спасибо Благодарностей отдано 
    404
    Спасибо Благодарностей получено 
    1,207
    Поблагодарили
    394 сообщений
    Mentioned
    48 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

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

    Цитата Сообщение от svofski Посмотреть сообщение
    В Питоне может быть и невелика будет разница, но я бы попробовал.
    Тоже нужно будет прикинуть и измерить скорость обоих вариантов. Хотя в Python я ещё ни разу не использовал вызов функции по значению из списка - пользовался только вызовом по словарю, как в этом эмуляторе. И даже не знаю осуществимо ли это? Видимо, осуществимо.

    Я уже получил довольно много полезных советов, обязательно воспользуюсь ими всеми. Мне бы сейчас заставить работать систему при варианте хранения регистров в memoryview. Мало того, что оно просто сейчас перестало работать, так ещё и всякие нюансы всплыли. Например, вариант, предложенный Titus'ом:

    Код:
    reg_A = (reg_A << 1) | (reg_A >> 7);
    при таком методе хранения работать не будет, например, если reg_A == 0xFF. Как только сдвинутся биты внутри первых скобок я получу ошибку, что это значение не может хранится в байте. Вот и приходится огород городить из временных переменных, что явно не идёт на руку скорости эмуляции.
    Последний раз редактировалось CityAceE; 27.12.2018 в 15:46.
    С уважением, Станислав.

  2. #12
    Guru
    Регистрация
    08.10.2005
    Адрес
    Москва
    Сообщений
    13,651
    Спасибо Благодарностей отдано 
    1,248
    Спасибо Благодарностей получено 
    1,842
    Поблагодарили
    706 сообщений
    Mentioned
    67 Post(s)
    Tagged
    1 Thread(s)

    По умолчанию

    Цитата Сообщение от CityAceE Посмотреть сообщение
    Приведённый тобой пример будет работать в Python без каких-либо изменений, даже точки с запятой убирать не придётся Спасибо, я поизучаю такой вариант, попробую померить скорость и если будет выигрыш, то применю.
    Замечу, что reg_A должен быть формата uint8, иначе придется сделать иначе.

    Это фрагмент из моего эмулятора Z80. Он очень быстрый. Ну очень) Куда уж быстрее)
    Последний раз редактировалось Titus; 27.12.2018 в 15:41.

  3. #13
    Guru Аватар для svofski
    Регистрация
    20.06.2007
    Адрес
    С.-Петербург
    Сообщений
    4,116
    Спасибо Благодарностей отдано 
    800
    Спасибо Благодарностей получено 
    658
    Поблагодарили
    403 сообщений
    Mentioned
    22 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Цитата Сообщение от CityAceE Посмотреть сообщение
    Хотя в Python я ещё ни разу не использовал вызов функции по значению из списка - пользовался только вызовом по словарю, как в этом эмуляторе. И даже не знаю осуществимо ли это? Видимо, осуществимо.
    Конечно осуществимо. И из списка и из тупли.

    Написал незамысловатый бенчмарк. С современными компами и интерпретируемыми языками уровня питона такие бенчмарки мало толку дают. У меня получается разброс в 10% между запусками, слишком много внешних воздействий. В среднем, как мне показалось, тупля незначительно опережает список, список незначительно опережает словарь, но в общем это ловля блох и вряд ли эмулятор ускорится в два раза от такой переделки. Хотя в реальном коде разница может оказаться другой и, учитывая то, что попробовать вообще ничего не стоит, по-моему стоит попробовать

    Код:
    import time
    
    def foo(): return 'foo'
    def bar(): return 'bar'
    
    disp=[foo if i & 1 else bar for i in range(256)]
    dict={}
    for i in range(256):
        dict[i] = foo if i & 1 else bar
    
    
    niter = 100000000
    
    print("dispatch using list")
    start_time = time.time()
    for i in range(niter):
        u = disp[i & 255]()
    elapsed_time = time.time() - start_time
    print("elapsed time=", elapsed_time)
    
    print("dispatch using dictionary")
    start_time = time.time()
    for i in range(niter):
        u = dict[i & 255]()
    elapsed_time = time.time() - start_time
    print("elapsed time=", elapsed_time)
    
    tust=tuple(disp)
    print("dispatch using tuple")
    start_time = time.time()
    for i in range(niter):
        u = tust[i & 255]()
    elapsed_time = time.time() - start_time
    print("elapsed time=", elapsed_time)
    - - - Добавлено - - -

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

  4. #14
    Master
    Регистрация
    26.03.2005
    Адрес
    Ivanovo
    Сообщений
    640
    Спасибо Благодарностей отдано 
    5
    Спасибо Благодарностей получено 
    3
    Поблагодарили
    1 сообщение
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    CityAceE, в ассоциативной таблице выборка по ключу это поиск в хеш таблице. Операция O(1) формально, но на практике довольно сложная. Выборка из линейного массива это просто вычисление смещения. В Питоне может быть и невелика будет разница, но я бы попробовал.
    Нет. Это не так. Для ключа типа int это поиск ровно такой-же как и смещение в массиве. В питон3.6 и выше это поведение еще более оптимизировали.
    @CityAceE: Оставь диктом. Флаги у тебя тоже верно сделаны, т.к. смысла тащить их везде в виде битмаски абсолютно не нужно. Титус прав насчет расчетов, но ошибается насчет переносимости. В питон битовые операции будут сильно медленнее чем обычная математика. Если уж на то пошло, то можно использовать какую-нибудь библиотеку. Тот-же rlca переписаный слегка из pyzx:
    Код:
    def rlca():
        global _f3, _f5, _fN, _fH, _fC
        ans = _A[0]
        c = (ans & 0x80) != 0
        ans = (((ans << 1) | 0x01) if c else (ans << 1)) % 256
        _f3 = ((ans & F_3) != 0)
        _f5 = ((ans & F_5) != 0)
        _fN = False
        _fH = False
        _fC = c
        _A[0] = ans
        return 4
    - - - Добавлено - - -

    Написал тестик:
    Код:
    from random import randint
    import timeit
    def foo(): return 'foo'
    def bar(): return 'bar'
    disp=[foo if i & 1 else bar for i in range(256)]
    def test(): u = disp[randint(0, 255)]()
    timeit.timeit(test, number=100000000)
    2,511099100112915 сек.

    Код:
    from random import randint
    import timeit
    def foo(): return 'foo'
    def bar(): return 'bar'
    disp={i: (foo if i % 2 else bar) for i in range(256)}
    def test(): u = disp[randint(0, 255)]()
    timeit.timeit(test, number=100000000)
    2,5191421508789062 сек.

    Весьма показательно. 0.3% разницы на 1 миллионе вызовов.
    Последний раз редактировалось Q-Master; 27.12.2018 в 21:49.

  5. #15
    Guru Аватар для svofski
    Регистрация
    20.06.2007
    Адрес
    С.-Петербург
    Сообщений
    4,116
    Спасибо Благодарностей отдано 
    800
    Спасибо Благодарностей получено 
    658
    Поблагодарили
    403 сообщений
    Mentioned
    22 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Цитата Сообщение от Q-Master Посмотреть сообщение
    Нет. Это не так. Для ключа типа int это поиск ровно такой-же как и смещение в массиве. В питон3.6 и выше это поведение еще более оптимизировали.
    Питон трудный язык

    У меня не получилось запустить тесты в таком виде. Я добавил print() и уменьшил на порядок число итераций:
    Код:
    from random import randint
    import timeit
    def foo(): return 'foo'
    def bar(): return 'bar'
    disp=[foo if i & 1 else bar for i in range(256)]
    def test(): u = disp[randint(0, 255)]()
    print("list...")
    print(timeit.timeit(test, number=10000000))
    
    disp={i: (foo if i % 2 else bar) for i in range(256)}
    def test(): u = disp[randint(0, 255)]()
    print("dict...")
    print(timeit.timeit(test, number=10000000))
    И хотя это не принципиально, но все же вопрос:
    Код:
    $ python3 testqmaster.py
    list...
    11.997851000051014
    dict...
    11.946656999993138
    Это i7 8550U, python 3.6.5, WSL. Что же за камень делает в 10 раз больше за 2.5 сек?
    Больше игр нет

  6. #16
    Master
    Регистрация
    26.03.2005
    Адрес
    Ivanovo
    Сообщений
    640
    Спасибо Благодарностей отдано 
    5
    Спасибо Благодарностей получено 
    3
    Поблагодарили
    1 сообщение
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Цитата Сообщение от svofski Посмотреть сообщение
    Питон трудный язык

    У меня не получилось запустить тесты в таком виде. Я добавил print() и уменьшил на порядок число итераций:
    Код:
    from random import randint
    import timeit
    def foo(): return 'foo'
    def bar(): return 'bar'
    disp=[foo if i & 1 else bar for i in range(256)]
    def test(): u = disp[randint(0, 255)]()
    print("list...")
    print(timeit.timeit(test, number=10000000))
    
    disp={i: (foo if i % 2 else bar) for i in range(256)}
    def test(): u = disp[randint(0, 255)]()
    print("dict...")
    print(timeit.timeit(test, number=10000000))
    И хотя это не принципиально, но все же вопрос:
    Код:
    $ python3 testqmaster.py
    list...
    11.997851000051014
    dict...
    11.946656999993138
    Это i7 8550U, python 3.6.5, WSL. Что же за камень делает в 10 раз больше за 2.5 сек?
    Я косяк с копипастой. Там 1000000 итераций, как оно скопипастилось как 100000000 - фиг знает + это было на 2.7, а вот на 3.7 с массивом - 3.174003737999996, с диктом - 3.1171019020000017, что показывает что дикт в 3.7 даже еще больше оптимизирован, чем я думал

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

  8. #17
    Guru Аватар для svofski
    Регистрация
    20.06.2007
    Адрес
    С.-Петербург
    Сообщений
    4,116
    Спасибо Благодарностей отдано 
    800
    Спасибо Благодарностей получено 
    658
    Поблагодарили
    403 сообщений
    Mentioned
    22 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Q-Master, понятно. Все это немного удивительно, потому что интуитивно все-таки даже очень простой хеш код это все равно лишняя операция, и в бакете может быть больше одного элемента. А индекс в массиве -- это просто индекс. Но понятно, что в Питоне все на самом деле не так просто.

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

    Скрытый текст


    list...
    12.346341000054963
    tuple...
    12.456940999953076
    dict...
    12.440088999923319

    list...
    12.06766299996525
    tuple...
    12.148910999996588
    dict...
    12.198226999957114

    list...
    12.217213000054471
    tuple...
    12.13867199991364
    dict...
    12.269977999967523
    [свернуть]
    Больше игр нет

  9. #18
    Administrator Аватар для CityAceE
    Регистрация
    13.01.2005
    Адрес
    г. Москва
    Сообщений
    4,575
    Записей в дневнике
    7
    Спасибо Благодарностей отдано 
    404
    Спасибо Благодарностей получено 
    1,207
    Поблагодарили
    394 сообщений
    Mentioned
    48 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Провёл оптимизацию по рекомендациям из этой ветки:

    - Перевёл хранение регистров и памяти в memoryview, переделал эмуляцию всех инструкций под такой формат
    - Заменил все операции & 0xF, & 0xFF и & 0xFFFF на более быстрые операции получения остатка от деления
    - Отказался от универсальной эмуляции i8080/Z80 и, соответственно от лишних проверок и флагов

    По списку вроде бы не много, но пришлось перелопачивать почти всё, а потом ещё долго искать почему перестало работать.

    Не стал менять хранение флагов, а также не стал переносить процессор в класс.

    Новая версия в первом посте.

    Всем спасибо за советы и рекомендации. Посмотрите текст скрипта, вдруг что-то ему можно улучшить и оптимизировать?

    Результат, конечно, есть, но он не слишком впечатляет (слева - v0.1, справа - v0.2):

    Последний раз редактировалось CityAceE; 29.12.2018 в 08:18.
    С уважением, Станислав.

  10. #19
    Administrator Аватар для CityAceE
    Регистрация
    13.01.2005
    Адрес
    г. Москва
    Сообщений
    4,575
    Записей в дневнике
    7
    Спасибо Благодарностей отдано 
    404
    Спасибо Благодарностей получено 
    1,207
    Поблагодарили
    394 сообщений
    Mentioned
    48 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Изменил логику обновления экрана. Результат порадовал!

    Слева - v0.2, справа - неопубликованная версия с оптимизацией вывода экрана:


    Ну, и для сравнения реальная скорость игры в Emu80:



    Ещё бы чуть-чуть и скорость стала бы реальной, но у меня закончились мысли, что можно ещё сделать, чтобы ускорить эмулятор.
    Последний раз редактировалось CityAceE; 31.12.2018 в 06:32.
    С уважением, Станислав.

  11. #20
    Guru Аватар для svofski
    Регистрация
    20.06.2007
    Адрес
    С.-Петербург
    Сообщений
    4,116
    Спасибо Благодарностей отдано 
    800
    Спасибо Благодарностей получено 
    658
    Поблагодарили
    403 сообщений
    Mentioned
    22 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Цитата Сообщение от CityAceE Посмотреть сообщение
    Ещё бы чуть-чуть и скорость стала бы реальной, но у меня закончились мысли, что можно ещё сделать, чтобы ускорить эмулятор.
    Так публикуй последние изменения, а то не видно что оптимизировать.
    Больше игр нет

Страница 2 из 7 ПерваяПервая 123456 ... ПоследняяПоследняя

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

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

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

Похожие темы

  1. Специалист-М
    от zx_ в разделе Специалист
    Ответов: 230
    Последнее: 18.12.2021, 14:41
  2. Ответов: 77
    Последнее: 21.01.2021, 00:14
  3. Тулзы для работы с образами на Python
    от Q-Master в разделе Утилиты
    Ответов: 4
    Последнее: 25.11.2014, 22:44
  4. Эмулятор ПК "Специалист" для Mac OS X
    от hdc в разделе Эмуляторы отечественных компьютеров
    Ответов: 1
    Последнее: 21.10.2009, 11:28
  5. Python
    от Black1980 в разделе Программирование
    Ответов: 12
    Последнее: 26.12.2006, 10:30

Ваши права

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