<bgdev />free

Вход Регистрация

neon
0

0 1 2 3

#129810 (ツ) waldorf
Създадено на 20.12.2024 , видяно: 330 пъти.
|

Good point. На теория е възможно. На практика не знам дали е вярно, но е валиден аргумент.

Точно разкарах printf & friends, че трябва да навра кво ли не 32кб - нормалния принтф иде с поддръжка за числа с плаваща запетая и лесно добавя едно 10-на кб. С целия ХАЛ за СТ32 + Зефир нишки, драйвери и т.н. и стана 31кб Т.е. трябва да имаш ама наистина много принтф, че да стане по оптимално да е отделна функция а не сдъвкан по време на компилация до отделни примитиви за печат. На практика почти никой не си играе да оптимизира чак до толкоа - или ползваш дебелия принтф със всички благинки или го махаш изцяло като мен. Въпреки, че Зефиря има и някакъв скопен вариант в който добавя само 2-3кб но мисля, че успях да го излъжа да подкарам логовете и пак да ми останат 10-на кб за моя код.

#129842 (ツ) |
Създадено на 20.12.2024 , видяно: 309 пъти.
waldorf

Точно разкарах printf & friends, че трябва да навра кво ли не 32кб - нормалния принтф иде с поддръжка за числа с плаваща запетая и лесно добавя едно 10-на кб. С целия ХАЛ за СТ32 + Зефир нишки, драйвери и т.н. и стана 31кб Т.е. трябва да имаш ама наистина много принтф, че да стане по оптимално да е отделна функция а не сдъвкан по време на компилация до отделни примитиви за печат. На практика почти никой не си играе да оптимизира чак до толкоа - или ползваш дебелия принтф със всички благинки или го махаш изцяло като мен. Въпреки, че Зефиря има и някакъв скопен вариант в който добавя само 2-3кб но мисля, че успях да го излъжа да подкарам логовете и пак да ми останат 10-на кб за моя код.

Е той Ребата каза, че използва някаква нестандартна имплементация. Ако не трябва да парсва неща като %04 и т.н. сигурно не е много сложна. Моята идея прави нещата малко по-оптимални в смисъл че се свързват само частите, които реално се използват. Ако нямаш %d, няма да се свърже печатането на десетични числа.

Иначе стандартната printf е ужасно голяма, поне в glibc. Тя вика и разните функции от i18n да знае в зависимост от стойността на LANG какво да използва за десетична запетая/точка и т.н. Не си спомням защо ми трябваше статично линкнато байнъри, но се хванах за главата като видях какво се случи като сложих един printf. :)

#129845 (ツ) Дон Реба
Създадено на 21.12.2024 , видяно: 297 пъти.
waldorf

Т.е. трябва да имаш ама наистина много принтф, че да стане по оптимално да е отделна функция а не сдъвкан по време на компилация

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

void  __attribute__((noinline)) printf(const char* format,...){
	if(!format||!serial)return;
	 __builtin_va_list argList;
	const char *p;
	char buf[12];// za printene na chisla
	__builtin_va_start(argList, format);
	for(p=format;*p;p++){
		char c=*p;
		char c1=p[1];
		if(c=='%'){
			unsigned int v=__builtin_va_arg(argList,unsigned int);
			char *dig=buf;// tuka malko habim edin simwol (buf[0]), ako startirame s buf-1 bi mogyl da se spesti
			if(c1=='d'||c1=='u'){
			}else
			if(c1=='%f'||c1=='%g'){
			}else
			if(c1=='x'||c1=='X'){
				c1-='x'-'a'+10;//konwertira go kym 'A' ili 'a' s ofset 10 za da prewyrne 0xA->'A' 
				do{
					dig++;
					*dig=v&0xf;
					*dig+=(*dig>9)?c1:'0';
					v>>=4;
				}while(v);
			}else
			if(c1=='s'){
				char *s=(char*)v;
				for(;*s;s++)putchar(*s);
			}else 
			if(!c1)break;
			p++;
			while(dig>buf){
				putchar(*dig);
				dig--;
			}
		}else if(c=='\\'){
			if(c1=='\\')putchar('\\');else
			if(c1=='n')putchar('\n');else
			if(c1=='r')putchar('\r');else
			if(c1=='t')putchar('\t');else
			if(!c1)break;
			p++;
		}else{
			putchar(c);
		}
	}
	__builtin_va_end(argList);

}


#129846 (ツ) Дон Реба
Създадено на 21.12.2024 , видяно: 297 пъти.
|

Иначе стандартната printf е ужасно голяма, поне в glibc. Тя вика и разните функции от i18n да знае в зависимост от стойността на LANG какво да използва за десетична запетая/точка и т.н.

аз дори само за това не бих ползвал стандартен принтф. това е толкова ВРЕДНО само по себе си, мани дето раздува кода но е ВРЕДНО, хората си пишат собствен принт и парсване за флоати само за да не се набодат на тоя хуй с принтф локализацията

#129901 (ツ) Евлампи
Създадено на 21.12.2024 , видяно: 270 пъти.
Дон Реба

хората си пишат собствен принт и парсване за флоати само за да не се набодат на тоя хуй с принтф локализацията

Принтф е програмиския аналог на тъждеството - бял ляп === църна локализация, даже да не ти трябва :)

#129930 (ツ) Дон Реба
Създадено на 22.12.2024 , видяно: 253 пъти.
BIGBUGEX

Обаче тая стратегия е добра и за конвертиране към десетична стойност. Цената е едно деление което е трудно да се избегне.

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


static u32 pow10[]={1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000};
....
				if(c1=='d'&&(int)v<0){// 
					putchar('-');// pechatame znaka
					v=-(int)v;// premahwame znaka, algorityma e za unsigned
				}
				int i;
				u32 rem=v;// towa koeto ostawa da se dopechata
				for(i=9;i>=0;i--){// skaniraneto e ot golemi kym malki, po reda na pechatane
					u32 p=pow10[i];//
					int c=0;// kolko pyti p se pobira w rem
					while(rem>=p){
						rem-=p;
						c++;
					}
					if(c||v>p||!i)putchar(c+'0');
				}


#129954 (ツ) BIGBUGEX
Създадено на 22.12.2024 , видяно: 233 пъти.
Дон Реба

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


static u32 pow10[]={1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000};
....
				if(c1=='d'&&(int)v<0){// 
					putchar('-');// pechatame znaka
					v=-(int)v;// premahwame znaka, algorityma e za unsigned
				}
				int i;
				u32 rem=v;// towa koeto ostawa da se dopechata
				for(i=9;i>=0;i--){// skaniraneto e ot golemi kym malki, po reda na pechatane
					u32 p=pow10[i];//
					int c=0;// kolko pyti p se pobira w rem
					while(rem>=p){
						rem-=p;
						c++;
					}
					if(c||v>p||!i)putchar(c+'0');
				}


Може да е по-добре за контролери които нямат 64 битов шифт. За последната цифра може да не се цикли, чуек. Тя си е готова в rem. И май ти спестява една проверка за !i.

				for(i=9;i;i--){// skaniraneto e ot golemi kym malki, po reda na pechatane
					u32 p=pow10[i];//
					int c=0;// kolko pyti p se pobira w rem
					while(rem>=p){
						rem-=p;
						c++;
					}
					if(c||v>p)putchar(c+'0');
				}
				putchar( rem + '0' );

#129965 (ツ) Дон Реба
Създадено на 22.12.2024 , видяно: 224 пъти.

прав си да

#129975 (ツ) Дон Реба
Създадено на 22.12.2024 , видяно: 215 пъти.

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



				u32 i,rem=v;// towa koeto ostawa da se dopechata
				for(i=0;i<9;i++){// skaniraneto e ot golemi kym malki, po reda na pechatane
					u32 c,p=pow10[i];//
					if(p>v)continue;
					for(c=0;rem>=p;c++)rem-=p;
					putchar(c+'0');
				}
				putchar(rem+'0');

#129978 (ツ) BIGBUGEX
Създадено на 22.12.2024 , видяно: 210 пъти.

Да, доста по-добре изглежда.

#130075 (ツ) BIGBUGEX
Създадено на 23.12.2024 , видяно: 177 пъти.

И се замислих, дали няма да се ускори подхода на Дон Реба ако имаме таблица на база 5. С двоично търсене и всички шукарии. И стана един мазаляк...

#define FIVESIZE 19

unsigned utos1( char *s, uint32_t val ) {
	static const uint32_t five[FIVESIZE] = {
		1,
		5,
		10,
		50,
		100,
		500,
		1000,
		5000,
		10000,
		50000,
		100000,
		500000,
		1000000,
		5000000,
		10000000,
		50000000,
		100000000,
		500000000,
		1000000000
	};
	
	unsigned i, j, b, e, c;
	
	for( b = 0, e = FIVESIZE, j = 0; e - b > 0; ) {
		i = ( b + e ) >> 1;
		
		if( val >= five[i] ) {
			j = i;
			b = i + 1;
		}else {
			e = i;
		}
	}
	
	for( i = j, j = 0; i > 1; ) {
		c = i & 1 ? 5: 0;
		val -= i & 1 ? five[i]: 0;
		i &= -2;
		
		while( val >= five[i] ) val -= five[i], c++;
		
		--i;
		i -= val < five[i];
		s[j++] = c + '0';
	};
	
	s[j++] = val + '0';
	s[j] = 0;
	
	return j;
}

#130079 (ツ) Дон Реба
Създадено на 23.12.2024 , видяно: 158 пъти.

putchar е десет пъти по-бавно от конверсията, оптимизация за скорост няма смисъл, по-добре размер.

0 1 2 3

neon
0

AsmBB v3.0 (check-in: 7544654b24928b93); SQLite v3.47.0 (check-in: 03a9703e27c44437);
©2016..2024 John Found; Licensed under EUPL. Powered by Assembly language Created with Fresh IDE