<bgdev />free

Вход

Отрязано от Апелации – за програмирането и общи приказки.
0

0 1 2 3
#86829 (ツ) Golden Gega
Създадено на 09.03.2023, видяно: 307 пъти.
johnfound

Кеширането е само един много частен случай

Еми не е, айде да не си припомняме какво е кеш и колко нива има в съвременните цпу-та.

#86830 (ツ) johnfound
Създадено на 09.03.2023, видяно: 300 пъти.
Golden Gega
johnfound

Кеширането е само един много частен случай

Еми не е, айде да не си припомняме какво е кеш и колко нива има в съвременните цпу-та.

Ние, конкретно в цитирания пост говорехме за съвсем друго кеширане, нямащо нищо общо с хардуера. Прочети пак.

#86832 (ツ) Golden Gega
Създадено на 09.03.2023, видяно: 290 пъти.
johnfound
Golden Gega
johnfound

Кеширането е само един много частен случай

Еми не е, айде да не си припомняме какво е кеш и колко нива има в съвременните цпу-та.

Ние, конкретно в цитирания пост говорехме за съвсем друго кеширане, нямащо нищо общо с хардуера. Прочети пак.

Джони, ако си беше правил сам базата данни вместо да ползваш sqlite щеше да забравиш неща като "кеширането е един много частен случай", смешното е че ти като майстор асемблерджия би трябвало доста по-добре да ги разбираш работите с кеша но в крайна сметка всички сме ученици и в тая професия.

#86837 (ツ) palavrov
Създадено на 09.03.2023, видяно: 277 пъти.

Моя коментар беше, че скоростта с която се четат данните от паметта е с пъти по бавна от скоростта с която ядрата паралелно циклят в процесора т.е. на едно четене от паметта процесора може да изпълни като нищо 100-на инструкции и при това положение става излишно да оптимизираш на ръка който ще се изпълни на за 20 ами за 10 инструкции - кел файда като процесора така и така трябва да чака докато се вреди за данни. Затова според мен кода генериран от модерен Ц/Ц++ компилатор е достатъчно добър, че да не го дооптимизирам. И по важното става как да си структурираш данните така, че нещата да стават бързо. Отделно, че има неща за които си заслужава да се оптимизира и такива за които не си заслужава - пак е въпрос на субективна преценка.

Това не трябва да се бърка с това на кой програмист кой език му е по лесен и си е свикнал. Джони се оправя на асемблер по добре отколкото болшинството програмисти биха се оправили на език от високо ниво - не виждам никаква причина да го убеждавам да не ползва асемблер. Напротив. Даже му се кефя на постоянството и резултатите. Но за мен избора отдавна е друг - където има ограничения откъм бързодействие, памет и т.н. предпочитам Ц, за всичко друго JS. Но най вече каквото клиента си поръча и плати.

#86838 (ツ) palavrov
Създадено на 09.03.2023, видяно: 276 пъти.
johnfound
palavrov

Не бе, говоря за четенето на самите стрингове, че ще ги прочетеш двойно - един път за да видиш колко са дълги и евентуално втори път за да сравниш байт по байт дали са еднакви.

Пак повтарям, за да видя колко са дълги стринговете не ми трябва да ги чета до края. Формата на стринговете, който се използва в StrLib е с префикс в който е записана дължината на стринга (тип Pascal, ако така ти е по-ясно). StrLen определя дължината на стринга за O(1), константно време, без да ги сканира.

Така че, ако стринговете са с различна дължина, цялата операция за сравнение става мигновена, за О(1), въобще без никакво сканиране на стринговете.

А, аз предположих, че работиш с null терминирани стрингове - пълно безумие са ама като са станали стандарт кой да предположи, че ползваш паскалски.

Между другото няма ли как да инлайнваш такива малки функции с макроси? То и това не е панацея защото като се инлайнва кода по често расте и съответно може да има обратен ефект ама има случаи в които за 2-3 инструкции ще извикаш функция с поне още толкова, ще запишеш параметри в стека. Отделно не знам fasm abi-то дали позволява да предаваш параметри в регистри. Те това са все неща които Ц/Ц++ компилатора би направил автоматично за тебе без ти губи времето и особено с LTO (link time optimisations) резултата често е перфектно генериран код.

#86840 (ツ) palavrov
Създадено на 09.03.2023, видяно: 271 пъти.
Дон Реба
johnfound
palavrov

Заради това, че процесора работи много по бързо отколкото се прочитат данните от паметта (да не говорим за диска) се получава така, че и да си оптимизирал кода си до дупка той ще се изпълни също толкова бавно колкото и по малко оптимизиран от компилатора защото бавното място е другаде.

Това изказване просто не е вярно.

всъщност е абсолютно вярно. софтуера днес е осезаемо по-бавен от преди 20 години защото за 20 години паметта продължи да нараства, но скоростта и - не. отделно преди 20 години софтуера беше офлайн, а днес масово си "приказва" по интернета. основно правило на блоатинга е - ако има ресурс ще се заеме. това прави съвременния софтуер консумиращ повече памет "защото има" от там и забавянето, а не щото не е оптимизиран. виж телефоните как процесора им е по-бавен, ама някак си всичко върви по-мазно от пц

То да е само това. Много платформи са проектирани по времето когато цената на паметта е била с пъти в повече от тази на процесорна инструкция. С времето паметта поевтинява толкова много, че тези стари дизайни започват да стават проблем ама си се ползват по инерция. Например всичките GUI-та.

#86849 (ツ) johnfound
Последно редактирано на 09.03.2023 от johnfound, видяно: 249 пъти.
palavrov

А, аз предположих, че работиш с null терминирани стрингове - пълно безумие са ама като са станали стандарт кой да предположи, че ползваш паскалски.

Библиотеката е съвместима и с null терминирани стрингове, ако случайно се налага да се използват, примерно върнати от външни библиотеки. Но тъй като това е фолбак, то съответно с такива стрингове бързодействието ще е влошено.

palavrov

Между другото няма ли как да инлайнваш такива малки функции с макроси? То и това не е панацея защото като се инлайнва кода по често расте и съответно може да има обратен ефект ама има случаи в които за 2-3 инструкции ще извикаш функция с поне още толкова, ще запишеш параметри в стека. Отделно не знам fasm abi-то дали позволява да предаваш параметри в регистри. Те това са все неща които Ц/Ц++ компилатора би направил автоматично за тебе без ти губи времето и особено с LTO (link time optimisations) резултата често е перфектно генериран код.

Разбира се, че има начин, но не обичам да го правя. Лично моето мнение е, че макросите не трябва да генерират повече от 4..5 инструкции изпълним код. Иначе в дългосрочна перспектива създават огромни проблеми и с производителността и с четимостта на кода и с възможностите за поддръжка.

Така че, ако ми трябва нещо да е инлайннато, то просто си го пиша на място. При това имам възможност да си го напиша именно за конкретният частен случай – вида на циклите, използването на регистрите, локалните променливи и т.н.

В асемблера няма понятие като ABI – можеш да си правиш каквото си искаш. Но предаването на параметри в регистрите, когато става въпрос за библиотечни функции не е добра идея. За някакви малки спомагателни функции, да, без проблем.

#86868 (ツ) realinformatik
Последно редактирано на 09.03.2023 от realinformatik, видяно: 226 пъти.
johnfound

В асемблера няма понятие като ABI – можеш да си правиш каквото си искаш. Но предаването на параметри в регистрите, когато става въпрос за библиотечни функции не е добра идея. За някакви малки спомагателни функции, да, без проблем.

Обаче нали кода който пишеш трябва да е в PE/ELF формат (за windows/linux) и трябва да правиш syscalls за да заделиш и получиш от OS пойнтер към динамичната памет/heap, т.е. поне при тези OSи си имаш процес и виртуална памет, нямаш достъп до физическата. И като правиш тези syscalls трябва да спазваш ABI конвенциите.

#86874 (ツ) johnfound
Създадено на 09.03.2023, видяно: 217 пъти.
realinformatik
johnfound

В асемблера няма понятие като ABI – можеш да си правиш каквото си искаш. Но предаването на параметри в регистрите, когато става въпрос за библиотечни функции не е добра идея. За някакви малки спомагателни функции, да, без проблем.

Обаче нали кода който пишеш трябва да е в PE/ELF формат (за windows/linux) и трябва да правиш syscalls за да заделиш и получиш от OS пойнтер към динамичната памет/heap, т.е. поне при тези OSи си имаш процес и виртуална памет, нямаш достъп до физическата. И като правиш тези syscalls трябва да спазваш ABI конвенциите.

Естествено. Но това е ABI-то на операционната система. При Уиндоус е едно, при Линукс съвсем друго.

А вътре в приложението, плюс библиотеките, които сам си пишеш можеш да си използваш каквото си искаш.

Разбира се, човек си изработва някакви правила и "стандарти", но специално за асемблера те са много плаващи и зависят повече от контекста в който се използва някаква конкретна функция.

Аз например масово използвам CF флага за връщане на булеви резултати, просто защото е супер удобно. Имам функции обаче, които връщат булев резултат в ZF.

Имам някои функции, които връщат по няколко резултата в няколко регистъра.

Ако в 90% функциите връщат резултат в EAX, то в някои случаи е по-удобно да се връща резултата примерно в EBX или в EDX, защото предварително е известно, че този резултат ще се пази дълго време, а EAX се използва като scratch променлива.

Такива фокуси в никой език от високо ниво не са възможни (или поне аз не знам такива езици).

#86878 (ツ) Golden Gega
Създадено на 09.03.2023, видяно: 205 пъти.
johnfound
realinformatik
johnfound

В асемблера няма понятие като ABI – можеш да си правиш каквото си искаш. Но предаването на параметри в регистрите, когато става въпрос за библиотечни функции не е добра идея. За някакви малки спомагателни функции, да, без проблем.

Обаче нали кода който пишеш трябва да е в PE/ELF формат (за windows/linux) и трябва да правиш syscalls за да заделиш и получиш от OS пойнтер към динамичната памет/heap, т.е. поне при тези OSи си имаш процес и виртуална памет, нямаш достъп до физическата. И като правиш тези syscalls трябва да спазваш ABI конвенциите.

Естествено. Но това е ABI-то на операционната система. При Уиндоус е едно, при Линукс съвсем друго.

А вътре в приложението, плюс библиотеките, които сам си пишеш можеш да си използваш каквото си искаш.

Разбира се, човек си изработва някакви правила и "стандарти", но специално за асемблера те са много плаващи и зависят повече от контекста в който се използва някаква конкретна функция.

Аз например масово използвам CF флага за връщане на булеви резултати, просто защото е супер удобно. Имам функции обаче, които връщат булев резултат в ZF.

Имам някои функции, които връщат по няколко резултата в няколко регистъра.

Ако в 90% функциите връщат резултат в EAX, то в някои случаи е по-удобно да се връща резултата примерно в EBX или в EDX, защото предварително е известно, че този резултат ще се пази дълго време, а EAX се използва като scratch променлива.

Такива фокуси в никой език от високо ниво не са възможни (или поне аз не знам такива езици).

Кое е фокус, да върнеш няколко резултата с една функция ли?

#86890 (ツ) johnfound
Създадено на 09.03.2023, видяно: 201 пъти.
Golden Gega

Кое е фокус, да върнеш няколко резултата с една функция ли?

Без копиране насам-натам из паметта.

#86912 (ツ) Golden Gega
Създадено на 10.03.2023, видяно: 187 пъти.

Дай нещо конкретно, ето казваш например да видим има ли функция дето връща 4 32-битови стойности

#86939 (ツ) palavrov
Създадено на 10.03.2023, видяно: 167 пъти.

gcc и clang май позволяваха да специфицираш в кои регистри са параметри и връщания резултат ... или пък беше Watcom C/C++ ... помня ли вече.

Ползването на регистри за параметри има един голям недостатък - компилатора непрекъснато преподрежда променливите в регистрите за да угоди на функцията която извиква т.е. ако ги подредиш по "правилен" начин параметрите на функциите може да спестиш някоя друга инструкция избягвайки това преподреждане.

Когато се предават през стека който пък от своя страна е добре кеширан колкото и да е парадоксално на практика може да се окаже по бързо отколкото спрямо когато са в регистри. Но и тук си има специфики защото ако стане прекъсване в този момент процесора трябва да запише всичко кеширано в бавната външна памет за да гарантира, че някоя друга нишка която също ползва тази памет ще види верните данни а не тези отпреди малко дори и когато въобще няма такава нишка.

#86946 (ツ) Golden Gega
Създадено на 10.03.2023, видяно: 158 пъти.

Едно време с делфинариума си беше купон да блъскаш асемблер - https://docwiki.embarcadero.com/RADStudio/Alexandria/en/Assembly_Procedures_and_Functions Но такива бяха времената, романтични, аз съм работил и във фирма (пак с делфи) където производителността беше топ изискване - ставаше дума за парсване на html - и стандартните библиотеки за низове се считаха и с право за относително бавни. ОБАЧЕ и тук го имаше тоя момент че обекта на парсването често се променяше, че имаше разни интеграции и модули, Джони може да се чуства горд, и там ползвахме sqlite т.е. нормална производствена обстановка. Така че разумния компромис си беше обработка с паскал, а не с асемблерски код

0 1 2 3

Отрязано от Апелации – за програмирането и общи приказки.
0

AsmBB v3.0 (check-in: a316dab8b98d07d9); SQLite v3.42.0 (check-in: 831d0fb2836b71c9);
©2016..2023 John Found; Licensed under EUPL. Powered by Assembly language Created with Fresh IDE