repstosw 18 6 мая, 2019 Опубликовано 6 мая, 2019 (изменено) · Жалоба Компилирую очередной "шедевр эмуляции" - эмулятор ядра ARM7TDMI. Ключи такие: Quote cl6x.exe -mv6740 --abi=eabi -O3 --opt_for_speed=5 --include_path="C:/CCS6.0.1/ccsv6/tools/compiler/ti-cgt-c6000_8.3.3/include" --include_path="C:/workspace_v6_0/BP_GBA/Port" --include_path="C:/workspace_v6_0/BP_GBA/API" --include_path="C:/workspace_v6_0/BP_GBA/FatFs" --include_path="../" --define=c6745 --symdebug:none --c99 --relaxed_ansi --float_operations_allowed=64 --printf_support=minimal --diag_warning=225 --diag_wrap=off --display_error_number --gen_func_subsections=on --dprel --sat_reassoc=on --fp_mode=relaxed -k --preproc_with_compile --preproc_dependency="ARM-NEW.pp" "ARM-NEW.cpp" Проблема: не хватает оперативной памяти компа чтоб завершить компиляцию. В диспетчере задач оптимизатор занимает около 3 ГБ памяти на пике. Затем благополучно вываливается ошибка: Quote >>>> Optimizer terminated abnormally >>>> in function _Z7arm_newv() >>>> in file "../ARM-NEW.cpp" >>>> ERROR - OUT OF MEMORY. This is caused by a defect in the TI C/C++ Optimizer. TI Customer Support may be able to suggest a workaround to avoid this. Upgrading to the newest version of the compiler may fix this problem. Contact TI in the E2E support forums at http://e2e.ti.com under "Development Tools", "TI C/C++ Compiler". See the link titled "Submitting an issue". We need to see this ENTIRE error message and a complete, reproducible test case including ALL of the command-line options. Include the .pp file created by option --preproc_with_comment >> Compilation failure gmake: *** [ARM-NEW.obj] Error 1 **** Build Finished **** Прикладываю сорец который не компилируется: ARM-NEW.cpp На -O2 тоже облом. Компилирует только на -O1, что не устраивает совсем! Что можно предпринять чтоб скомпилировать на максимальной оптимизации? Пилить сорец на части вроде не выйдет - там большой свитч на 6000 строк........ Изменено 6 мая, 2019 пользователем repstosw Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
repstosw 18 6 мая, 2019 Опубликовано 6 мая, 2019 (изменено) · Жалоба Сейчас спустился на версию компилятора 7.x.x уже целый час компилится, всё никак не может собраться: Quote "C:\\CCS6.0.1\\ccsv6\\utils\\bin\\gmake" -k ARM-NEW.obj 'Building file: ../ARM-NEW.cpp' 'Invoking: C6000 Compiler' "C:/CCS6.0.1/ccsv6/tools/compiler/c6000_7.4.24/bin/cl6x" -mv6740 --abi=eabi -O3 --symdebug:none --include_path="C:/CCS6.0.1/ccsv6/tools/compiler/c6000_7.4.24/include" --include_path="C:/workspace_v6_0/BP_GBA/Port" --include_path="C:/workspace_v6_0/BP_GBA/API" --include_path="C:/workspace_v6_0/BP_GBA/FatFs" --include_path="../" --relaxed_ansi --float_operations_allowed=64 --define=c6745 --diag_wrap=off --diag_warning=225 --display_error_number --gen_func_subsections=on --dprel --sat_reassoc=on --opt_for_speed=5 --fp_mode=relaxed --printf_support=minimal -k --preproc_with_compile --preproc_dependency="ARM-NEW.pp" "../ARM-NEW.cpp" Обратите внимание, пакет компилятора 32-битный, а не 64-битный. Хотя железо и ОС - 64 битные. Почему? Изменено 6 мая, 2019 пользователем repstosw Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 188 6 мая, 2019 Опубликовано 6 мая, 2019 · Жалоба 18 минут назад, __inline__ сказал: Что можно предпринять чтоб скомпилировать на максимальной оптимизации? Пилить сорец на части вроде не выйдет - там большой свитч на 6000 строк........ Думаю - не компилится, потому что там весь этот гигантский switch влуплён внутрь одного макроса. Скорее всего компилятор этот гигантский макрос и не может прожевать. 8 минут назад, __inline__ сказал: Обратите внимание, пакет компилятора 32-битный, а не 64-битный. Хотя железо и ОС - 64 битные. Почему? Не факт что и 64-битный этот гига-макрос прожуёт. На всякий случай: можете посмотреть настройки компилятора на предмет опций препроцессора. Может там что поможет. Если проблема именно в этом гигантском макросе. Для теста можете просто его обрезать и проверить - стало ли компилиться? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
repstosw 18 6 мая, 2019 Опубликовано 6 мая, 2019 (изменено) · Жалоба 30 minutes ago, jcxz said: Думаю - не компилится, потому что там весь этот гигантский switch влуплён внутрь одного макроса. Скорее всего компилятор этот гигантский макрос и не может прожевать. Не факт что и 64-битный этот гига-макрос прожуёт. На всякий случай: можете посмотреть настройки компилятора на предмет опций препроцессора. Может там что поможет. Если проблема именно в этом гигантском макросе. Для теста можете просто его обрезать и проверить - стало ли компилиться? Версия 7.4.24 успешно скомпилировала на максимально возможной с ним оптимизации. Пиковое потребление памяти - около 2 ГБ. Компилировалось - 1 час с небольшим. Но скорость кода им порождаемая, меньше, чем у 8.3.3 - так что пока проблема не решена. Чуть-позже посмотрю настройки и попробую отсечь часть кода. Результаты напишу. P.S. Под БлекФины Visual DSP v. 5.0 компилировал этот код 17 часов на стареньком компе 800 МГц с 64 МБ оперативы с Win98 :) Несколько лет назад! Изменено 6 мая, 2019 пользователем repstosw Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
repstosw 18 6 мая, 2019 Опубликовано 6 мая, 2019 · Жалоба Вот такой асм-листинг вышел - на 103 700 строк: ARM-NEW.rar Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_pv 53 6 мая, 2019 Опубликовано 6 мая, 2019 · Жалоба я правильно понял что он это действительно развернул в это в тысячи if else if else if else ... ? вместо того чтобы 16кБ флэша отдать под таблицу с указателями на функции, распилить этот switch на отдельные куски и сделать func_table [ ((opcode>>16)&0xFF0) | ((opcode>>4)&0x0F) ] (opcode); т.е. сделать один call вместо 4096 условных переходов (в худшем случае)? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
repstosw 18 6 мая, 2019 Опубликовано 6 мая, 2019 · Жалоба 13 minutes ago, _pv said: я правильно понял что он это действительно развернул в это в тысячи if else if else if else ... ? вместо того чтобы 16кБ флэша отдать под таблицу с указателями на функции, распилить этот switch на отдельные куски и сделать func_table [ ((opcode>>16)&0xFF0) | ((opcode>>4)&0x0F) ] (opcode); т.е. сделать один call вместо 4096 условных переходов (в худшем случае)? Насколько ускорит выполнение кода таблица с указателями? И как заставить компилятор switch делать в таблицу, а не условия? TI Compiler не поддерживает GCC финт ушами наподобие: goto &&OPCODE[n]; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 188 6 мая, 2019 Опубликовано 6 мая, 2019 · Жалоба 20 минут назад, _pv сказал: я правильно понял что он это действительно развернул в это в тысячи if else if else if else ... ? вместо того чтобы 16кБ флэша отдать под таблицу с указателями на функции, распилить этот switch на отдельные куски и сделать Почему вы так решили? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_pv 53 6 мая, 2019 Опубликовано 6 мая, 2019 · Жалоба 4 minutes ago, jcxz said: Почему вы так решили? Я не решил, а спросил, так как с ассемблером TMSов не знаком, но увидел кучу переходов. А потом пролистал немного дальше и всё-таки нашел таблицу со смещениями для переходов, если опять же правильно её понял. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
repstosw 18 7 мая, 2019 Опубликовано 7 мая, 2019 (изменено) · Жалоба Проблема решилась: вынес все CASE16 отдельно CPP/H-файл и оформил в виде функции . Успешно скомпилировал. А в исходном файле немного изменил алгоритм и добавил вызов той самой функции. Иными словами - распилил на 2 C-файла и получил 2 объектника. Изменено 7 мая, 2019 пользователем repstosw Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 188 7 мая, 2019 Опубликовано 7 мая, 2019 · Жалоба 3 часа назад, __inline__ сказал: Проблема решилась: вынес все CASE16 отдельно CPP/H-файл и оформил в виде функции . Успешно скомпилировал. А в исходном файле немного изменил алгоритм и добавил вызов той самой функции. Иными словами - распилил на 2 C-файла и получил 2 объектника. Когда-то, когда я писал свой эмулятор, выполнявшийся ещё на i486, то обошёлся вообще без такой таблицы: реализацию ~95% всех эмулируемых кодов команд смог засунуть в ограниченное число байт памяти (вроде в 16 байт/инструкция влезло) и переход делал просто сдвинув код инструкции влево на 4 бита и прибавив к базовому адресу таблицы эмуляции команд. Получилось предельно быстрое ветвление - никаких выборок из памяти. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
repstosw 18 9 мая, 2019 Опубликовано 9 мая, 2019 (изменено) · Жалоба On 5/8/2019 at 6:03 AM, jcxz said: Когда-то, когда я писал свой эмулятор, выполнявшийся ещё на i486, то обошёлся вообще без такой таблицы: реализацию ~95% всех эмулируемых кодов команд смог засунуть в ограниченное число байт памяти (вроде в 16 байт/инструкция влезло) и переход делал просто сдвинув код инструкции влево на 4 бита и прибавив к базовому адресу таблицы эмуляции команд. Получилось предельно быстрое ветвление - никаких выборок из памяти. Сделал через таблицу переходов (точнее - вызовов функций). Работает, дало небольшое увеличение в скорости. Код такой: void opcode_0(void) { ... } void opcode_1(void) { ... } void opcode_2(void) { ... } void opcode_3(void) { ... } typedef void (*Handler)(void); #pragma DATA_ALIGN(32) const Handler ARM_Handler[0x1000]= { opcode_0,opcode_1,opcode_2,opcode_3, ........ }; void arm_new(void) { opcode= ..... ...... ARM_Handler[opcode](); } Таблица и код находятся в SDRAM, она закеширована по L1D, L1P, L2. При попытке скопировать таблицу ARM_Handler[0x1000] в L2 и выполнить код ARM_Handler_L2[opcode]() сославшись на эту таблицу(в L2) приводит к вылету - контроллер сбрасывается. Хочется скопировать эту таблицу в L2 и дёргать указатели функций из неё, чтобы исключить промахи кеша (ведь выборки из ARM_Handler[] случайные). Почему с копированием таблицы в L2 указатели на функции становятся невалидными? (Кеш L2 я сбрасываю, если что, хотя это тут не нужно, так как L2 некешируемый регион и любая запись в него приводит к фактической записи данных) Связано ли это как-то с адресацией данных? Может относительная адресация вместо абcолютной ? Пробовал разные data access model: - на near вообще не собирается, так как на смещение надо более 15 бит (линковщик ругается), far_aggregates и far работает. Общий объём бинарного образа - около 1 МБ Включена опция: DP relative addressing - она ускоряет выбор данных или нет? Изменено 9 мая, 2019 пользователем repstosw Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 188 9 мая, 2019 Опубликовано 9 мая, 2019 · Жалоба 5 часов назад, __inline__ сказал: Почему с копированием таблицы в L2 указатели на функции становятся невалидными? (Кеш L2 я сбрасываю, если что, хотя это тут не нужно, так как L2 некешируемый регион и любая запись в него приводит к фактической записи данных) Разоритесь уже наконец-то на самый дешёвый эмулятор. Чтоб не тратить время на всякую ерунду. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
repstosw 18 9 мая, 2019 Опубликовано 9 мая, 2019 (изменено) · Жалоба 1 hour ago, jcxz said: Разоритесь уже наконец-то на самый дешёвый эмулятор. Чтоб не тратить время на всякую ерунду. Мне не нужны даже даром готовые эмуляторы игровых приставок (особенно дешёвые) - интересно самому сделать. Расцениваю как плевок в мою сторону. Спасибо. Удачи! Изменено 9 мая, 2019 пользователем repstosw Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_pv 53 9 мая, 2019 Опубликовано 9 мая, 2019 · Жалоба видимо ТСу не раз высказывали про существование готовых китайских поделок, программных эмуляторов приставок которые можно запустить на всяких raspi и т.д. :) но под самым дешевым эмулятором jcxz имел ввиду какой-нибудь xds110. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться