FreeBasic
Главная
Вход
Регистрация
Четверг, 13.11.2025, 22:00Приветствую Вас Гость | RSS
[ Новые сообщения · Участники · Правила форума · Поиск · RSS ]
  • Страница 2 из 2
  • «
  • 1
  • 2
FMOD Ex 4.44.08 - заголовочные файлы + примеры
DarkDemonДата: Понедельник, 06.10.2025, 10:26 | Сообщение # 16
Генерал-майор
Группа: Друзья
Сообщений: 270
Репутация: -1
Статус: Offline
Кстати zamabuvaraeu пишет интересные вещи, сколько бы весила винда если бы её сбилдили правильно. Т.е. не 15, а 1.5 гигабайта,
можно было бы целиком в память загнать. SSD были бы не нужны.

7-ка это последняя винда, которой можно пользоваться без SSD диска, сильно не страдая. Про проблемы, когда 10-ка
до мяса драконит диск, думаю, все слышали.

Конечно, сам не считаю килобайты так пристально, не тот возраст уже, чтобы считать "зёрнышки для курочки", но помню, как это
делал под DOS-ом. Самый компактный код получался конечно же на ассемблере, ни один ЯП такой код генерировать не умел.

Цитата
FreeBASIC крут. Это как си, только приведённый в чувство.

А как у нас FB-шников с совместимостью версий в ретроспективе?
Я не понимаю почему люди этого не видят. Мол обновились, а на всю сделанную работу комьюнити - пофиг? Да как так?
Вот electrik сокрушается мол нет каких-то крутых библ, так вообще нихера уже нет, всё поотваливалось))) вся многолетняя
работа комьюнити коту под хвост. Сколько людей пострадало. Лично у меня по половине кодархива отваливалось сразу,
сколько протрахался с тем, чтобы восстановить свои исходники, годы работы потеряны.
Ну просто потому что не любитель обновляться на каждый чих. У меня в принципе всегда отвращение и скепсис к обновлениям,
потому что 99% софта, который использовал, после обновления с гарантией давало проблемы. Начиная ещё со старых скайпов,
и заканчивая изменением интерфейса(как правило в более неудобный) любого другого софта.

К слову видел твои методики настройки сборки, это интересно, была бы ещё к этому всему понятная документация
и толкование.

Цитата
перевод исходного кода PureBasic в FASM — это не оптимизация. Это трансляция «как есть»

Мне, кстати, нравится подход трансляции как есть в ASM. Он чистый, максимально прозрачный. Там трудно налажать и сделать
неработоспособным. Это минимализм. И это действительно круто. Было...

Цитата
он уже перекатился из FASM на си и так «осовременил» встроенные библиотеки, что вместо программ на 15 килобайт компилятор содаёт Bloatware на 150 килобайт.

А я говорил, что будет не очень хорошо. Просто кто-то захотел больше платформ. А больше платформ = больше гемора.
При том что вроде бы как у них не офигеть какой бизнес, шли слухи, что оно их даже не кормит.
 
zamabuvaraeuДата: Среда, 15.10.2025, 12:43 | Сообщение # 17
Полковник
Группа: Друзья
Сообщений: 177
Репутация: 5
Статус: Offline

Цитата
А как у нас FB-шников с совместимостью версий в ретроспективе?

Это баги. Не стоит строить на них свои программы.
А то будет как с WinAPI, когда какое‐нибудь древнее решение из 1993 года приходится поддерживать до сих пор, в 2025. Просто чтобы сломанные программы работали.


Цитата
Мне, кстати, нравится подход трансляции как есть в ASM. Он чистый, максимально прозрачный
Тогда оптимизация невозможна.
Возьмём функцию вычисления факториала:

Код
Private Function FactorialTailRecursive(ByVal X As Integer, ByVal Accumulator As Integer)As Integer
   
   If X = 0 Then
      Return Accumulator
   End If
   
   Dim Steps As Integer = X - 1
   Dim Prod As Integer = Accumulator * X
   
   Return FactorialTailRecursive(Steps, Prod)
   
End Function

Private Function Factorial(ByVal X As Integer)As Integer
   
   Dim Prod As Integer = FactorialTailRecursive(X, 1)
   
   Return Prod
   
End Function

Нужно вычислить факториал от 8. Вызываем:

Код
Dim argument As Integer = 8
Dim fact As Integer = Factorial(argument)

' Выводим в формате "число! = значение":
printf(!"%d! = %d\r\n", argument, fact)


Включаем оптимизацию и видим, что громоздкие вычисления функции превратились в константу:

Код

  mov   r8d, 40320
   mov   edx, 8
   lea   rcx, "! = "
   call   printf
Это всего лишь несколько байт кода.
Если бы мы транслировали в ассемблер как есть, это были бы килобайты кода, а потом:

Цитата
сколько бы весила винда если бы её сбилдили правильно. Т.е. не 15, а 1.5 гигабайта,
можно было бы целиком в память загнать. SSD были бы не нужны.
 
DarkDemonДата: Четверг, 16.10.2025, 17:53 | Сообщение # 18
Генерал-майор
Группа: Друзья
Сообщений: 270
Репутация: -1
Статус: Offline
Цитата
Тогда оптимизация невозможна.

Оптимизация нужна только тогда, когда прога написана бездарно и работает как говно.
Когда твоя прога написана нормально и всё учтено, даже банальная прямая трансляция даёт приемлемый результат.
Разумеется, транслятор должен уметь в минимум: выравнивание и ещё ряд аспектов, то чего требует железо.
И просто грамотно переводить код на асм. Потому что плохая расстановка ветвей условий может снизить
производительность(например будет больше переходов).
Как бы смысл автооптимизаций это делать то, что не может нормально делать человек, т.е. все эти просчёты
спаривания инструкций, куда оно там попадёт в кеш или не попадёт, вот эти все вещи которыми ты на ВУ
не сильно управляешь. Но оно не должно знать за программиста как идеологически правильно кодить.

Цитата zamabuvaraeu ()
Возьмём функцию вычисления факториала:

Озвученная ситуация - это вообще ответственность исключительно прогера.
Потому что именно он должен понимать, что вычислять константы при хардкодинге - не нужно.
Т.е. именно он, а не коммилятор за него.

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

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

Пишу о том, что это не решает в целом всех проблем, это не какая-то панацея на все случаи.
Приятно когда оно есть, но в целом всегда было пофиг, есть или нет, нет - значит делаем сами нормально, руками.
И хренов тот прогер, который при отсутствии этого в ЯП - не вывезет просто руками, мол за ним надо постоянно
выгребать из бинарника кучи дерьма. Одно дело конечно когда прогер об этом не знает, когда это какие-то
зависимые библы или рантаймы, что не его рук дело, совсем другое - когда это его собственный код.

Цитата
Это всего лишь несколько байт кода.
Если бы мы транслировали в ассемблер как есть, это были бы килобайты кода

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

Цитата
Это баги. Не стоит строить на них свои программы.

Говорил не про тот баг с 0.23.0. А про то, что при каждом апгрейде у меня отваливалось по пол кодархива.
И постоянно то хедеры, то с кастами что-то не так, то синтаксис поменяют(что вообще бред).
Чё тут говорить, если они свои же примеры не проверяли, годами тащат то, что не работает.
С меня хватило этих приключений, обновлять больше не буду... 1.10.1 теперь до конца. Устал.

Добавлено (16.10.2025, 20:01)
---------------------------------------------
Цитата
Оптимизация нужна только тогда, когда прога написана бездарно и работает как говно.

Поясню. От тебя никто не требует писать на 100% оптимально, во-первых неизвестно что такое 100%.
Я например, абсолютно точно не смогу писать как демщики середины 90-х. По понятным причинам
такой уровень не потянет вообще никто, во всяком случае с форумов никого не знаю кто так умеет
в оптимизацию. И вообще рядовые кодеры - там немного другие скиллы.
Во-вторых, с пистолетом никто к стенке не поставит. Для себя выделил критерий качества, что мол
сколько работы ты вложил в прогу - так работать и будет. Сколько времени потратил на оптимизацию
- так и будет. Это объективно, честно и понятно. Тут не схалявить, вообще никак. Профи это замечают.

И ухудшение этого параметра оно не всегда зависит от программиста. Рядовой юзер который мирится
с этим говном - это его заслуга в большей степени. Потому что кодер чешет репу и думает - "а нахрена
я парюсь, если людям и так достаточно". И вот так получилось что выросло поколение тех, кто не парится
вообще, т.е. им "нет нужды заморачиваться". Значит пользователь сам заслужил это дерьмо это его проблема.
Если бы винды никто не купил - тогда Microsoft уже бы чесали репу. А они уже 20 лет жируют в бабле,
там мозгов уже не осталось, зачем они будут укладывать винду в гигабайт, ведь тогда им вендоры
по партнёркам не заплатят, как они будут продавать новое железо? Люди тогда десятилетиями будут
на старом сидеть.

На самом деле если так подумать с точки зрения развития, то бизнес в IT выглядит как - "мудак на мудаке".
Да не секрет что C2D, C2Q - отличнейшие процы были. И пока софт в конец не ожирел - всё летало.
И самая нормальная ось - XP примерно и весила на харде 1,5 Гб и в памяти от 200 до 500. Это дальше
уже пошёл неадекват с размерами и пожиранием ресурсов.
Страшно стало, когда даже неплохие Core i7 перестали выгребать.
Мы то знаем что есть оси типа колибри. Т.е. компактно и быстро можно писать. Был бы только спрос
и ясное мышление у окружающих "мимокрокодилов" пользующихся благами IT.


Сообщение отредактировал DarkDemon - Четверг, 16.10.2025, 20:05
 
zamabuvaraeuДата: Пятница, 17.10.2025, 08:44 | Сообщение # 19
Полковник
Группа: Друзья
Сообщений: 177
Репутация: 5
Статус: Offline
Возьмём простой массив и установим все его элементы:


Код
Dim Vector(265) As Integer = Any
For i As Integer = LBound(Vector) To UBound(Vector)
   Vector(i) = i
Next
Казалось бы, такая простая конструкция. Смотрим в промежуточный код. И что мы видим? Страшного Монстра:


Код
int64 VECTOR$1[266];
__builtin_memset( (int64*)VECTOR$1, 0, 2128ll );
struct $8FBARRAY1Iu7INTEGERE tmp$589$1;
*(int64**)&tmp$589$1 = (int64*)VECTOR$1;
*(int64**)((uint8*)&tmp$589$1 + 8ll) = (int64*)VECTOR$1;
*(int64*)((uint8*)&tmp$589$1 + 16ll) = 2128ll;
*(int64*)((uint8*)&tmp$589$1 + 24ll) = 8ll;
*(int64*)((uint8*)&tmp$589$1 + 32ll) = 1ll;
*(int64*)((uint8*)&tmp$589$1 + 40ll) = 49ll;
*(int64*)((uint8*)&tmp$589$1 + 48ll) = 266ll;
*(int64*)((uint8*)&tmp$589$1 + 56ll) = 0ll;
*(int64*)((uint8*)&tmp$589$1 + 64ll) = 265ll;
{
   int64 I$2;
   I$2 = 0ll;
   label$134:;
   {
      *(int64*)((int64)(int64*)VECTOR$1 + (I$2 << (3ll & 63ll))) = I$2;
   }
   label$132:;
   I$2 = I$2 + 1ll;
   label$131:;
   if( I$2 <= 265ll ) goto label$134;
   label$133:;
}

А теперь засунем массив внутрь структуры  и сделаем то же самое:


Код
Type IntegerVector
   vec(265) As Integer
End Type

Dim Vector As IntegerVector = Any ' Выключить бессмысленное обнуление массива
For i As Integer = LBound(Vector.vec) To UBound(Vector.vec)
   Vector.vec(i) = i
Next


Получаем красиво:


Код
struct $13INTEGERVECTOR VECTOR$1;
{
   int64 I$2;
   I$2 = 0ll;
   label$138:;
   {
      *(int64*)((uint8*)&VECTOR$1 + (I$2 << (3ll & 63ll))) = I$2;
   }
   label$136:;
   I$2 = I$2 + 1ll;
   label$135:;
   if( I$2 <= 265ll ) goto label$138;
   label$137:;
}

К сожалению, такие штуки как "*(int64*)((uint8*)" и "(I$2 << (3ll & 63ll))", не устраняются простым способом, это нужно патчить компилятор. Но вот эти портянки инициализации дескриптора массива будут в коде всегда, даже если они не понадобятся.

А когда используется тип String, то там на каждый чих память создаётся и уничтожается:


Код
Dim Hello As String = "Hello"
Dim World As String = "World"
Dim Concat As String = Hello & " " & World

Из этих трёх строк кода получается Ужасный Монстр:


Код
FBSTRING TMP$593$1;
FBSTRING TMP$594$1;
FBSTRING HELLO$1;
fb_StrInit( (void*)&HELLO$1, -1ll, (void*)"Hello", 6ll, 0 );
FBSTRING WORLD$1;
fb_StrInit( (void*)&WORLD$1, -1ll, (void*)"World", 6ll, 0 );
FBSTRING CONCAT$1;
__builtin_memset( &TMP$593$1, 0, 24ll );
FBSTRING* vr$18 = fb_StrConcat( &TMP$593$1, (void*)&HELLO$1, -1ll, (void*)" ", 2ll );
__builtin_memset( &TMP$594$1, 0, 24ll );
FBSTRING* vr$21 = fb_StrConcat( &TMP$594$1, (void*)vr$18, -1ll, (void*)&WORLD$1, -1ll );
fb_StrInit( (void*)&CONCAT$1, -1ll, (void*)vr$21, -1ll, 0 );
fb_StrDelete( (FBSTRING*)&CONCAT$1 );
fb_StrDelete( (FBSTRING*)&WORLD$1 );
fb_StrDelete( (FBSTRING*)&HELLO$1 );


Поэтому в своём коде я обхожу стороной массивы и String.

Добавлено (17.10.2025, 08:46)
---------------------------------------------
Забыл показать массив внутри структуры:

Код
Type IntegerVector
    vec(265) As Integer
End Type
 
DarkDemonДата: Пятница, 17.10.2025, 16:31 | Сообщение # 20
Генерал-майор
Группа: Друзья
Сообщений: 270
Репутация: -1
Статус: Offline
Цитата zamabuvaraeu ()
Казалось бы, такая простая конструкция. Смотрим в промежуточный код. И что мы видим? Страшного Монстра

Инфа о таких ситуациях это конечно здорово и мне бы понимать, что там значат на си эти все закорючки.
Просто если лазить каждый раз туда под капот, то программированием заниматься будет некогда.
А капота там два, один сишный и второй ещё и асм, который тоже не идеальный, про что говорил в своё время
автор VirtualDub.
По поводу памяти на строку, если бы я писал свой компилятор то сделал бы также, т.е. строки в памяти, а не в стеке.
Всё что можно тут сделать это буферизацию на определённое кол-во длины строки.
Поясню: дело тут не в скорости и не в простоте, а в универсальности, потому что стеком гибко управлять
в рантайме - трудно. Можно, наверное, завести свой стек и переназначить, но это тоже не единоразовая операция,
вдруг чуваку потребуется в строку сгрузить толстый файл. Люди так делают, уже сталкивался. И после закрытия что будет?
Будет висеть этот ненужный стек, придётся это всё контролировать. Это считай свой сборщик мусора.
Конечно проще сделать банальными аллоками.
И возможно допустить написание волшебного оптимизатора, который будет видеть объём использования строк
и выделять те которые заведомо копеечные - в стеке. Тут у меня вопросов не будет. Но я не хочу чтобы компиль
под капотом содержал монстра сборщика(если только это будет не мой самописный).

Добавлено (17.10.2025, 16:38)
---------------------------------------------
Вообще на особые потребности, на страх и риск юзера - они могли бы сделать что-то типа:

Код
DIM STACK a AS STRING

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


Сообщение отредактировал DarkDemon - Пятница, 17.10.2025, 16:43
 
zamabuvaraeuДата: Суббота, 18.10.2025, 07:42 | Сообщение # 21
Полковник
Группа: Друзья
Сообщений: 177
Репутация: 5
Статус: Offline

Цитата
который будет видеть объём использования строк
и выделять те которые заведомо копеечные - в стеке

Нет, нельзя:
1. Функция завершилась — стек уничтожен, всё что было на стеке — всё уничтожено. Все строки тоже уничтожены. Все указатели становятся недействительными. При попытке обращения к недействительному указателю — неопределённое поведение. Например, Access Vulvalation (но это не гарантируется).
2. Библиотеки ничего не знают про эти штуки.
 
DarkDemonДата: Суббота, 18.10.2025, 11:03 | Сообщение # 22
Генерал-майор
Группа: Друзья
Сообщений: 270
Репутация: -1
Статус: Offline
Цитата
2. Библиотеки ничего не знают про эти штуки.

Да вот тоже про это и подумал. Жопа как ни крути, конвертировать накладно. И собственно свинарник в бинарнике.

Цитата
Функция завершилась

Ну компилятор то видит, в пределах функции оно или нет. В принципе он и по использованию видит.
Если никуда в параметре не передаётся - думаю можно. Вообще в плане софта глобально не думаю
что будет весомый выигрыш. Локально могут быть какие-то ускорения. Но если крутится какой-то тяжёлый
движок - то скорее всего влияние будет минимально.
Я бы не стал этим заморачиваться.


Сообщение отредактировал DarkDemon - Суббота, 18.10.2025, 11:05
 
zamabuvaraeuДата: Суббота, 18.10.2025, 14:34 | Сообщение # 23
Полковник
Группа: Друзья
Сообщений: 177
Репутация: 5
Статус: Offline

Цитата
Вообще на особые потребности, на страх и риск юзера - они могли бы сделать что-то типа:

Код
DIM STACK a AS STRING
Впрочем, совсем забыл.
Есть строки которые всегда на стэке создаются: ZString и WString.
 
DarkDemonДата: Вторник, 21.10.2025, 07:31 | Сообщение # 24
Генерал-майор
Группа: Друзья
Сообщений: 270
Репутация: -1
Статус: Offline
Кстати в новом компиле есть какое-то дерьмо с UNION внутри пространств имён.
Колупаюсь в OpenGL, хотел себе сделать удобное преобразование цвета,
подумал что можно через объёдинение в типе UDT, пишу так

Код

  TYPE CVet FIELD = 1
     UNION
       RGBT AS ULONG            '  Все каналы сразу
       TYPE
         R AS UBYTE             '  Красный
         G AS UBYTE             '  Зелёный
         B AS UBYTE             '  Синий
         T AS UBYTE             '  Прозрачность
       END TYPE
     END UNION
  END TYPE

Потом объявляю переменную внутри NAMESPACE, снаружи делаю USING, после него кладу что-то в эту переменную

Код
BackCv.RGBT = RGB(50, 50, 50)

И хренак, потом оказывается, что она пустая, т.е. 0, 0, 0. Несколько часов рыл, заебался, сотни тестов делал.
Поменял на ULONG - сразу всё заработало, мгновенно, сразу ни одного косяка. И тут если я вдруг допустил ошибку
в структуре, то какого хера компилятор мне не скажет об этом, а берёт и спокойно это дерьмо компилирует?
Более того потом оказалось что G - то что зелёный внутри структуры, компиль пишет не определён, хотя
другие - почему то определены, проверял даже побуквенно, написано было без ошибок.

В общем весело, дерьмо у них там какое-то, напортачили ребятки...

Потому пишу, надо делать максимально просто, вообще без наворотов, простая блин трансляция мне бы
столько нервов и времени уберегла бы... И сколько ещё таких "рифов" об которые уже почти лысый череп можно сломать...
 
haavДата: Вторник, 21.10.2025, 13:01 | Сообщение # 25
Генералиссимус
Группа: Администраторы
Сообщений: 1438
Репутация: 50
Статус: Offline
Да вроде нормально:


Код
TYPE CVet FIELD = 1 
    UNION 
        RGBT AS ULONG            '  Все каналы сразу 
        TYPE 
        R AS UBYTE             '  Красный 
        G AS UBYTE             '  Зелёный 
        B AS UBYTE             '  Синий 
        T AS UBYTE             '  Прозрачность 
        END TYPE 
    END UNION 
END TYPE 
 
namespace QQQ 
    dim BackCv as CVet 
End Namespace 
 
using QQQ 
BackCv.RGBT = RGBA(50, 50, 50 , 0) 
? BackCv.R , BackCv.G , BackCv.B , BackCv.T , BackCv.RGBT


Вы сохраняете власть над людьми покуда оставляете им что-то…Отберите у человека все, и этот человек уже будет неподвластен вам…
 
DarkDemonДата: Вторник, 21.10.2025, 15:25 | Сообщение # 26
Генерал-майор
Группа: Друзья
Сообщений: 270
Репутация: -1
Статус: Offline
Цитата
Да вроде нормально:

В пробирке, в сухом вакууме у меня тоже вопросов не было. К сожалению, код уже отвязал от этой штуки и он претерпел
много изменений, поэтому баг вряд ли покажу(обратно переписывать в вид с багом - слишком много работы ), но он там
точно был, потому как при простом присваивании(после присваивания с ненулевыми значениями) значение занулялось.
Как и почему это происходило мне понять не удавалось, отсматривал все места, через которые проходил код, там не было
этой переменной, нечему было её модифицировать и как только заменил её на обычный ULONG, сразу всё начало работать
как надо(она участвовала в формировании цвета для очистки экрана, я писал туда именно RGBA(50, 50, 50) должен был иметь
этот цвет, но был чёрный, с самим OpenGL это не было связано, это проверял, писал в этом же месте  GLClearColor и цвет
менялся).

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

Добавлено (22.10.2025, 03:22)
---------------------------------------------

Цитата
потом оказалось что G - то что зелёный внутри структуры, компиль пишет не определён

Вот это кстати был мой косяк. Ещё до добавления этой структуры ещё с прошлого исходника тащил
за собой после неймспейса #DEFINE G MiniGL, чтобы названо было красиво, а обращаться по одной букве.
Как оно могло повлиять на то что лежит внутри неймспейса - одному богу известно. Возможно даже баг
с очищением был из-за этого, но это не точно и тут мне не очень понятна логика, т.е. внутри пространства
имён у меня стояло обращение к G и компиль не ругался. Т.е. получается что, как только переменная(а в данном
случае тип) с этим именем выходит из пространства имён он "материализуется" и дефайн начинает над
ним надругаться, при том что дефайн стоит до использования переменной. Т.е. это уже особенности компиляции
как она работает, мне ещё в это не хватало влезать. В общем интересные метаморфозы.
Чем сложнее инструментарий, тем больше проблем. Где-нибудь писюльку одну поставишь за год до этого,
10 раз забудешь про неё - и писец.


Сообщение отредактировал DarkDemon - Вторник, 21.10.2025, 15:26
 
  • Страница 2 из 2
  • «
  • 1
  • 2
Поиск: