Jump to content

    

__inline__

Участник
  • Content Count

    1012
  • Joined

Everything posted by __inline__


  1. Вот я и говорю, что фолты по невыровненному доступу - почти добрая половина ошибок при работе с памятью. А ещё меня дураком пытаются выставить такие как jcxz ! Просто завидуют: ведь Allwinner уделал C6745 до слёз , а для jcxz этот DSP - это "священная корова" Вот и хейтит он мои посты теперь, прикапываясь по мелочам. hacker_fox тоже уже на подходе, почти...
  2. В каком месте? Кто этот кто-то и какие левые советы он дал в этой теме? В каком месте и кого именно я ввёл в заблуждение? Каких коллег вы имеете в виду? Перечислите.
  3. Вы наверное будете удивлены, что мне совершенно безразлично что вы там считаете о моей адекватности или её отсутствии. Слишком всё уныло обобщаете. Я даже не буду тратить своё время на дальнейшее разжёвывание. В данном случае я просто стебусь и не более. В таком состоянии бесполезно меня взывать к ответам. Тем более данный форум - ничем не обязывает. Так что смиритесь с тем, что мои посты будут у вас вызывать раздражение. Более того, вы можете внести в ЧС мой ник и более сообщений от меня не увидите. Но вот так воспаляться по каждому моему посту - это уже похоже на ничем непрекрытое хейтерство )))) Найдите себе другого субъекта для битья. А ещё лучше - поберегите свои нервы и время!
  4. Ага, по вашему STM32H743 это не Cortex-M7 ? Тут вы и попались! Не хочу...
  5. У меня на BlackFin и STM32 были исключения из-за невыровненной памяти. А вот в C6745 просто читался мусор, пока не заиспольовал _mem(), _mem8(). Тоесть компилятор почему-то подставляет инструкции, не учитывающие доступ по невыровненным адресам. Пользуясь случаем, глянул в сорцы эмуля СЕГи, который когда-то адаптировал под C6745 и увидел, что использование инструкций через интринсики, дало увеличение производительности чуть-ли не в 2 раза в рендерере эмулятора: вместо 4-х побайтовых обращений используется - ОДНА инструкция с невыровненным доступом, что очень сильно увеличивает скорость: #define ALIGN_LONG 0 /* !!! unaligned word */ #if ALIGN_LONG /* Or change the names if you depend on these from elsewhere.. */ #undef WRITE_LONG static __inline__ void WRITE_LONG(void *address, uint32 data) { *((uint8 *)address++) = data; *((uint8 *)address++) = data>> 8; *((uint8 *)address++) = data>>16; *((uint8 *)address ) = data>>24; return; } #endif #if ALIGN_LONG /* Draw a single 8-pixel column */ #define DRAW_COLUMN(ATTR, LINE) \ atex = atex_table[(ATTR >> 13) & 7]; \ src = (uint32 *)&bg_pattern_cache[(ATTR & 0x1FFF) << 6 | (LINE)]; \ WRITE_LONG(dst++, *src++ | atex); \ WRITE_LONG(dst++, *src++ | atex); \ ATTR >>= 16; \ atex = atex_table[(ATTR >> 13)/* & 7*/]; \ src = (uint32 *)&bg_pattern_cache[(ATTR & 0x1FFF) << 6 | (LINE)]; \ WRITE_LONG(dst++, *src++ | atex); \ WRITE_LONG(dst++, *src++ | atex); \ #else #define DRAW_COLUMN(ATTR, LINE) \ atex = atex_table[(ATTR >> 13) & 7]; \ src = (uint32*)&bg_pattern_cache[(ATTR & 0x1FFF) << 6 | (LINE)]; \ _mem4(dst++) = (_mem4(src++) | atex); \ _mem4(dst++) = (_mem4(src++) | atex); \ ATTR >>= 16; \ atex = atex_table[(ATTR >> 13) & 7]; \ src = (uint32*)&bg_pattern_cache[(ATTR & 0x1FFF) << 6 | (LINE)]; \ _mem4(dst++) = (_mem4(src++) | atex); \ _mem4(dst++) = (_mem4(src++) | atex); \ #endif #if ALIGN_LONG /* Draw a single 16-pixel column */ #define DRAW_COLUMN_IM2(ATTR, LINE) \ atex = atex_table[(ATTR >> 13) & 7]; \ offs = (ATTR & 0x03FF) << 7 | (ATTR & 0x1800) << 6 | (LINE); \ if(ATTR & 0x1000) offs ^= 0x40; \ src = (uint32 *)&bg_pattern_cache[offs]; \ WRITE_LONG(dst++, *src++ | atex); \ WRITE_LONG(dst++, *src++ | atex); \ ATTR >>= 16; \ atex = atex_table[(ATTR >> 13)/* & 7*/]; \ offs = (ATTR & 0x03FF) << 7 | (ATTR & 0x1800) << 6 | (LINE); \ if(ATTR & 0x1000) offs ^= 0x40; \ src = (uint32 *)&bg_pattern_cache[offs]; \ WRITE_LONG(dst++, *src++ | atex); \ WRITE_LONG(dst++, *src++ | atex); \ #else #define DRAW_COLUMN_IM2(ATTR, LINE) \ atex = atex_table[(ATTR >> 13) & 7]; \ offs = (ATTR & 0x03FF) << 7 | (ATTR & 0x1800) << 6 | (LINE); \ if(ATTR & 0x1000) offs ^= 0x40; \ src = (uint32*)&bg_pattern_cache[offs]; \ _mem4(dst++) = (_mem4(src++) | atex); \ _mem4(dst++) = (_mem4(src++) | atex); \ ATTR >>= 16; \ atex = atex_table[(ATTR >> 13) & 7]; \ offs = (ATTR & 0x03FF) << 7 | (ATTR & 0x1800) << 6 | (LINE); \ if(ATTR & 0x1000) offs ^= 0x40; \ src = (uint32*)&bg_pattern_cache[offs]; \ _mem4(dst++) = (_mem4(src++) | atex); \ _mem4(dst++) = (_mem4(src++) | atex); \ #endif Если же выравнивание никак не учитывать (не применять _mem*() или не делать побайтовое чтение) , то эмулятор просто повисает и вылетает в data misaligned Exception :) Класс! Вполне исчерпывающий ответ!
  6. Компилятор здесь не причём. Я говорил о случае, когда идёт чтение short по адресу не кратному 2 или long по адресу не кратному 4. Хотя бы вот такой пример: short a=*(short*)(0xC0000001); int b=*(int*)(0xC0000007); Надеюсь, не надо пояснять, к чему приведут такие обращения к памяти? Мы не знаем как автор топика обращается к данным, а это значит, что имею право предположить что выше
  7. __Мои__ предположения: 1) Нет контакта со стробом чтения или других контактов (проверить качество контактов MPU, DRAM и на предмет К.З.) 2) Неисправная память или не подходит по времянкам 3) Ошибка в соединении DRAM и MPU. Плата своя или фирменная? 4) Что-то не так с выравниванием данных в программе (short д.б. выравнены на 2 байта, long - на 4, long long - на 8). Без текста программы тестилки - гадание на кофейной гуще.
  8. https://vrtp.ru/index.php?showtopic=29688&st=30 https://vrtp.ru/index.php?act=Attach&type=post&id=765613
  9. Уже поздно, кнопка Edit Post отсутствует. К тому же вы также внесли свою лепту и размножили этот пост: Да и чего вы так боитесь? Умный всё поймёт правильно. А дурак не осилит. Тем более вы писали: Ваша просьба удовлетворена.
  10. А меня задевает, что у вас позиция: "Я - Д'Артаньян, а остальные пи****сы", иначе как понять ваше высказывание про: Скажу так, что мне необязательно разбираться в кишках аллокатора, более того, я туда не лез. Так что вы лжёте по поводу: Интересно, кто вы собственно такой, чтобы давать такие заключения другим людям? Вам легче станет, если скажу, что "замедление-сбой-подвисание" - это следствие того, что malloc вернул NULL, и программа пошла шагать дальше, а не застопорилась, как сделано в последнем случае? Вы имеете право думать о чём угодно. Я имею право писать о чём угодно. В интернете, вам никто ничем не обязан. А раз выкладываете свой код для пользования другими, будьте готовы увидеть любые отзывы, в том числе невыгодные вам ! Ваш диалог уже получается НЛП какое-то: насквозь прошпигован угрозами и призывом к ответственности. Далеко пойдёте... Напоследок скажу, ваш аллокатор неоптимально использует пул памяти, по сравнению с другими. Надеюсь, я оставил вас довольным своим ответом! И скажите спасибо, что вашему аллокатору выделил своё время ДВАЖДЫ!
  11. Декодер H264 напрашивается. Там хорошее сжатие между фреймами и опенсорцный. Можно настроить качество не хуже JPEG. Странные клиенты. Чем ведро многоядерное по типу планшета их не устроило?
  12. Убедили! Всё-же ещё раз выделил квант своего времени и ещё раз всё проверил, сделал контрольную проверку возвращаемого значения после malloc. На голом железе. Там один поток. Есть прерывание для подкачки данных для звука, но там статическое распределение - буфер постоянной длины: обычный массив. Проверка показала, что malloc вернул NULL спустя какое-то время, дисплей покрасился в красный цвет, и далее я сделал вечное зацикливание. Недостаточно памяти. Данный аллокатор либо неэффективно (по сравнению с другими) использует кучу, либо куча сильно фрагментировалась. Пул 24 Мегабайта. Адрес пула 0xC2000000 - выравнивание - овердофига, чем надо. Штатный и zltig'овский аллокаторы с этим пулом работают, ошибок выделения памяти нет. Условия теже самые. Ниже обёртка, на которой тестировались все сторонние аллокаторы: /* o1.cpp cpp-wrapper for o1heap */ #include <string.h> //#include <stdio.h> #include <stddef.h> #include "o1heap.h" #include "API.h" //это API для работы с дисплеем, звуком, и т.п. static O1HeapInstance *o1i; #define HEAP_MEMORY_SIZE (24UL*0x100000UL) /* 24 МБ */ //static char HEAP_MEMORY[HEAP_MEMORY_SIZE] __attribute__ ((aligned (64))); //это для винды static char *HEAP_MEMORY=(char*)0xC2000000; //с этого адреса лежит пул кучи (свободный участок, неиспользуемый более никем) extern "C" void *malloc(size_t size) { static char f=1; if(f) { o1i=o1heapInit((void*)HEAP_MEMORY,HEAP_MEMORY_SIZE,NULL,NULL); //одноразово инитим аллокатор f=0; } void *r; if(!size) { // printf("malloc size=0\n"); return NULL; } r=o1heapAllocate(o1i,size); // if(r)printf("malloc=%d\n",size); // else printf("malloc error: not enougth memory\n"); if(r==NULL) //если выделить не удалось { ClearVRAM(COLOR_RED); //заливаем буфер видео красным цветом OutLCD(); //выводим буфер на дисплей while(1); //зацикливаем навечно } return r; } extern "C" void free(void *ptr) { // printf("free\n\n"); if(ptr==NULL)return; o1heapFree(o1i,ptr); } extern "C" void *calloc(size_t num,size_t size) { // printf(" CALLOC "); size_t ns=num*size; void *r=malloc(ns); if(r)memset(r,0,ns); return r; } extern "C" void *realloc(void *ptr,size_t newsize) { // printf(" REALLOC "); if(ptr==NULL)return malloc(newsize); //только выделяем if(newsize==0) //только освобождаем { free(ptr); return NULL; } void *new_ptr=malloc(newsize); memcpy(new_ptr,ptr,newsize); //копируем старый фрагмент в новый free(ptr); return new_ptr; } void *operator new(size_t sz) { // printf(" NEW 1 "); return malloc(sz); } void *operator new[](size_t sz) { // printf(" NEW 2 "); return malloc(sz); } void operator delete(void *ptr) { // printf(" DELETE 1 "); free(ptr); } void operator delete[](void *ptr) { // printf(" DELETE 2 "); free(ptr); }
  13. В ARMCC это делается через эмбид ресурсов через ASM-файлы. В GCC это делается через objdump + внешние extern В других, где эмбида нет - только конверсией BIN to H. А если разом всю анимацию из памяти(1) разжать в память(2), затем играть из памяти(2)? Затем освободить память(2), а из памяти (1) новую анимацию в память(2) ит.п.?
  14. Бенчмарки не использую (оставим их учёным и академикам для лабораторных исследований сферических коней в вакууме и для маркетологических статистик не имеющих ничего общего с реальностью), а выкладывать целиком весь код целевой программы нет ни желания, ни прав. Проблема вылезала не сразу, а по прошествию какого-то времени. Полагаю, алгоритм того аллокатора что-то не учёл. Иными словами, он не резистентен к случаям, которые предусмотрены в штатных аллокаторах (C6000+ и GNU ARM) и в аллокаторе, от zltigo. Я сомневаюсь в вашем авторстве того кода. Скорее всего вам стало скучно и прикалываетесь.
  15. С этим как раз всё ОК. Программе нужно выравнивание, намного бОльшее, чем требует аллокатор. Если я об этом не пишу, то это не значит, что этого не сделано. В данном случае этот момент не представлен общественности, так как посчитал эту элементарщину неуместной публикации. Любой сторонний аллокатор проверяется вначале подобными проверками. Снова не угадали. README я читаю, хотя бы ради того, чтобы сэкономить личное время, - узнать что надо вызвать для инита и использования. Эти "третьесортные бенчмарки", как вы выразились, со штатным аллокатором ведут игру ОТ и ДО без эксепшенов. Аллокатор zltigo также работает успешно ОТ и ДО (не считая выкрутасов mingw вначале). А этот аллокатор завалил работу программы через пару секунд, при этом несколько аллокаций-освобождений всё-же успешно произошли. Значит что-то пошло не так! Сомневаюсь! Просто решили потроллить. Проблема решена, читайте выше, даже штатный аллокатор вернули! P.S. https://electronix.ru/forum/index.php?app=core&module=members&controller=profile&id=35348 Дата последнего поста: October 15, 2014 Прошло 7 лет с тех пор... Странно это всё. В последнее время часто вижу на форуме выходящих из долгой спячки персонажей. Тенденция?
  16. Самый большой бэкдор - в башке человека. С таким подходом вам нужно содержать собственную силиконовую фабрику и разрабатывать свои кристаллы со своей архитектурой. И не забыть тщательно проверять кадров при приёме на работу. Если по существу, то давление есть - 100%! Даже в крупных игровых конторах есть требование заказчика встраивать функции в код игр, назначение которых известно только заказчику - программисты просто исполняют приказ. Естественно, исходный текст этих функций никто не видел, дают как extern. Полагаю, сбором телеметрии такие анальные зонды не ограничиваются. Как пример - удалённо загрузить код и исполнить его на машине пользователя. С помощью коллбэков это делается запросто (путём передачи управления в секцию данных). Туда же online-апдейт фирмвари ST Link для контроллеров STM
  17. Если в памяти хранить запакованный ZLIB'ом ресурс, затем при отображении его распаковывать - это будет довольно быстро. Тоесть в образе прошивки скомпонованы ресурсы сжатые ZLIB (на ПК предварительно с самым сильным сжатием -9 ), а при обращении к ним делается прозрачная распаковка(из памяти конечно). В играх так и сделали: заменили fopen, fread, fclose на свои - которые читают из памяти якобы файлы (на самом деле - сжатые образы в памяти). Правда тогда нужно будет организовать некий хедер (наподобие как таблица FAT) из которого как минимум будут извлекаться: имя ресурса, его размер и смещение относительно базового адреса ресурса. Что-то типа своего Data-Bundle. Так кстати в играх укатывают все ресурсы данных в один файл, который можно пристыковать к программе (GCC это может "изкаропки", для остальных - через конверсию bin to h) . А если взять smart-RLE-сжатие, то можно прямо побайтно налету разжимать картинки ))) Но по степени сжатия RLE хуже ZLIB. ZLIB ещё хорош тем, что если кто-то нехороший попытается "сломать" данные, то процесс распаковки завершится с ошибкой и можно просто завершить работу программы, обломав такого "товарища". Для усиления эффекта можно шифрование данных сверху прикрутить. Это защита для любителей патчить ресурсы или их извлекать в своих целях. Кстати, грядёт новый стандарт Си, надеюсь разработчики компилеров не прозевают и сделают все __полезные__ нововведения: https://habr.com/ru/company/badoo/blog/503140/ Особенно вот это наконец-то будет кросс-платформенно: const int music[] = { #embed int "music.wav" }; Мне здесь больше дерзкая китайская выходка против игровых копирасторов понравилась И решь шла не о Кобре-Сталлоне, а о японском Кобре. Вот этот товарищ: И этот : - разные люди, не пересекающиеся друг с другом.
  18. Случайно на али-экспресс увидел такую майку с Коброй : Была Контра - стал Кобра Времена меняются... Так, а со сжатием как дела обстоят? Мы когда делаем игры, поступаем так: сжимаем всё что сжимается ZLIB и кладём на SD карту. Затем когда что-то нужно подгрузить для конкретного уровня игры - лезем в динамический список - грузим и разжимаем в память то что нужно. Уровень заканчивается - освобождаем ресурс памяти. Далее из нового списка грузим в память и разжимаем объекты для нового уровня. И т.д. Ресурсы игры разношерстные: звуки, музыка, спрайтовые атласы, карта уровня, динамические списки, таблицы атрибутов. За всё про всё пока хватало кучи на 24 МБ на разжатые данные. Хотя общий объём сжатых данных на SD-карте - около 40 МБ. Cам код игры сейчас около 700 кБ для ARM и чуть более 1 МБ для C6745 (у обоих - жёсткая оптимизация по скорости, размер кода при этом неоптимален)
  19. Из всего вышеперечисленного мне интересен только бОльший размер памяти. Хотя держусь пока в пределах 32 МБ (приложениям хватает. Больше всего - расходы на HEAP. Затем STACK, а потом лишь BSS, ZI. И в последнюю очередь RO/text )
  20. Часто так выходит, что решаешь проблему X, а на самом деле причина скрыта в проблеме Y. Так и в этом случае: думал что аллокатор памяти тормозит, а оказалось было слабое место в игре. Более подробнее здесь: https://gamedev.ru/code/forum/?id=255201 И здесь: Всем спасибо, кто откликнулся! Проблемное место, где было замедление: Результат: Результат заснят здесь (с 40-й секунды): https://www.youtube.com/watch?v=lCq6wd2YA10&t=40
  21. Если сравнить V3s и S3, то по каким показателям S3 вам кажется привлекательнее?