реклама на сайте
подробности

 
 
3 страниц V  < 1 2 3  
Reply to this topicStart new topic
> Показать число с leading zeros.
SM
сообщение Jan 21 2015, 14:21
Сообщение #31


Гуру
******

Группа: Свой
Сообщений: 7 946
Регистрация: 25-02-05
Из: Moscow, Russia
Пользователь №: 2 881



Что-то у вас косяк с уровнем оптимизации. Это пишется в несколько команд ассемблера.

Для особо тупых компиляторов, можно еще подоптимизировать:

CODE

void ItoA(char * str, int number)
{
static int num_table[9] = {10000000, 1000000,100000,10000,1000,100,10,1,0};
int p=0;
char *str_p = str;
int i;
int tmp;

tmp = num_table[p++];
do {
i='0'; while ( (number-=tmp) >= 0) i++;
number += tmp;
*str_p++=i;
} while (tmp=num_table[p++]);

*str_p++=0;

}
Go to the top of the page
 
+Quote Post
CrimsonPig
сообщение Jan 21 2015, 14:36
Сообщение #32


Местный
***

Группа: Участник
Сообщений: 329
Регистрация: 23-04-14
Пользователь №: 81 502



Цитата(Jenya7 @ Jan 21 2015, 14:18) *
в принципе int num_table[9] = {10000000, 1000000,100000,10000,1000,100,10,1,0}; можно вынести из тела функции...


Зачем ? Засорять пространство имен всякими локальными именами - очень плохая идея.
Объявите этот массив внутри функции как
const int num_table[9] = {...}
Хотя нормальный компилятор и так должен был догадаться, что это константы.

Go to the top of the page
 
+Quote Post
SM
сообщение Jan 21 2015, 14:40
Сообщение #33


Гуру
******

Группа: Свой
Сообщений: 7 946
Регистрация: 25-02-05
Из: Moscow, Russia
Пользователь №: 2 881



Цитата(CrimsonPig @ Jan 21 2015, 17:36) *
const int num_table[9] = {...}


не const, а static. Да, это мое упущение. Этому на стеке не место.

Вот что генерирует TI CCS из последнего кода (16 инструкций):

CODE

_ItoA:
;* --------------------------------------------------------------------------*
LDR V9, $C$CON1 ; |11|
.dwpsn file "ccs.c",line 12,column 0,is_stmt
LDR A4, [V9, #0] ; |11|
;* --------------------------------------------------------------------------*
;* BEGIN LOOP ||$C$L1||
;*
;* Loop source line : 12
;* Loop closing brace source line : 16
;* Known Minimum Trip Count : 1
;* Known Maximum Trip Count : 4294967295
;* Known Max Trip Count Factor : 1
;* --------------------------------------------------------------------------*
||$C$L1||:
$C$DW$L$_ItoA$2$B:
SUBS A2, A2, A4 ; |13|
MOV A3, #48 ; |13|
BMI ||$C$L3|| ; |13|
; BRANCHCC OCCURS {||$C$L3||} ; |13|
$C$DW$L$_ItoA$2$E:
;* --------------------------------------------------------------------------*
;* BEGIN LOOP ||$C$L2||
;*
;* Loop source line : 13
;* Loop closing brace source line : 13
;* Known Minimum Trip Count : 1
;* Known Maximum Trip Count : 4294967295
;* Known Max Trip Count Factor : 1
;* --------------------------------------------------------------------------*
||$C$L2||:
$C$DW$L$_ItoA$3$B:
.dwpsn file "ccs.c",line 13,column 0,is_stmt
SUBS A2, A2, A4 ; |13|
ADD A3, A3, #1 ; |13|
BPL ||$C$L2|| ; |13|
; BRANCHCC OCCURS {||$C$L2||} ; |13|
$C$DW$L$_ItoA$3$E:
;* --------------------------------------------------------------------------*
||$C$L3||:
$C$DW$L$_ItoA$4$B:
STRB A3, [A1], #1 ; |15|
ADD A2, A4, A2 ; |14|
LDR A4, [V9, #4]! ; |16|
CMP A4, #0 ; |16|
.dwpsn file "ccs.c",line 16,column 0,is_stmt
BNE ||$C$L1|| ; |16|
; BRANCHCC OCCURS {||$C$L1||} ; |16|
$C$DW$L$_ItoA$4$E:
;* --------------------------------------------------------------------------*
MOV V9, #0 ; |18|
STRB V9, [A1, #0] ; |18|
.dwpsn file "ccs.c",line 20,column 1,is_stmt
$C$DW$4 .dwtag DW_TAG_TI_branch
.dwattr $C$DW$4, DW_AT_low_pc(0x00)
.dwattr $C$DW$4, DW_AT_TI_return
BX LR
; BRANCH OCCURS {LR}
Go to the top of the page
 
+Quote Post
Jenya7
сообщение Jan 21 2015, 14:45
Сообщение #34


Профессионал
*****

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



Цитата(AHTOXA @ Jan 21 2015, 19:43) *
Выбирайте!
---
Упс, уже дали эту ссылку sm.gif


проверил несколько функций из ссылки - листиг моего метода самый короткий.
Go to the top of the page
 
+Quote Post
SM
сообщение Jan 21 2015, 14:47
Сообщение #35


Гуру
******

Группа: Свой
Сообщений: 7 946
Регистрация: 25-02-05
Из: Moscow, Russia
Пользователь №: 2 881



Вот еще оптимизация (все время забываю про то, что цикл while, в отличие от do, дает лишнюю команду перехода, а это есть самое зло из всех зол - переходы):

CODE

void ItoA(char * str, int number)
{
static const int num_table[9] = {10000000, 1000000,100000,10000,1000,100,10,1,0};
int p=0;
char *str_p = str;
int i;
int tmp;

tmp = num_table[p++];
do {
i='0'-1; do { i++; } while ( (number-=tmp) >= 0);
number += tmp;
*str_p++=i;
} while (tmp=num_table[p++]);

*str_p++=0;

}


Листинг 15 инструкций sm.gif (а без *str_p++=0; всего 13)

CODE

_ItoA:
;* --------------------------------------------------------------------------*
LDR V9, $C$CON1 ; |11|
LDR A4, [V9, #0] ; |11|
.dwpsn file "ccs.c",line 13,column 0,is_stmt
MOV A3, #47 ; |13|
;* --------------------------------------------------------------------------*
;* BEGIN LOOP ||$C$L1||
;*
;* Loop source line : 13
;* Loop closing brace source line : 13
;* Known Minimum Trip Count : 1
;* Known Maximum Trip Count : 4294967295
;* Known Max Trip Count Factor : 1
;* --------------------------------------------------------------------------*
||$C$L1||:
$C$DW$L$_ItoA$2$B:
SUBS A2, A2, A4 ; |13|
ADD A3, A3, #1 ; |13|
BPL ||$C$L1|| ; |13|
; BRANCHCC OCCURS {||$C$L1||} ; |13|
$C$DW$L$_ItoA$2$E:
;* --------------------------------------------------------------------------*
$C$DW$L$_ItoA$3$B:
ADD A2, A4, A2 ; |14|
LDR A4, [V9, #4]! ; |16|
STRB A3, [A1], #1 ; |15|
CMP A4, #0 ; |16|
MOVNE A3, #47 ; |13|
BNE ||$C$L1|| ; |16|
; BRANCHCC OCCURS {||$C$L1||} ; |16|
$C$DW$L$_ItoA$3$E:
;* --------------------------------------------------------------------------*
MOV V9, #0 ; |18|
STRB V9, [A1, #0] ; |18|
.dwpsn file "ccs.c",line 20,column 1,is_stmt
$C$DW$4 .dwtag DW_TAG_TI_branch
.dwattr $C$DW$4, DW_AT_low_pc(0x00)
.dwattr $C$DW$4, DW_AT_TI_return
BX LR


так что, разбирайтесь со своим кривым компилятором, из какого пальца он там инструкции высасывает.
Go to the top of the page
 
+Quote Post
Jenya7
сообщение Jan 21 2015, 14:50
Сообщение #36


Профессионал
*****

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



Цитата(SM @ Jan 21 2015, 20:21) *
Что-то у вас косяк с уровнем оптимизации. Это пишется в несколько команд ассемблера.

Для особо тупых компиляторов, можно еще подоптимизировать:


эээ...я тут вспомнил что у меня атолик - фри версия...мля...нулевая оптимизация...все мои листинги не годяться. извиняюсь товарищи.
Go to the top of the page
 
+Quote Post
CrimsonPig
сообщение Jan 21 2015, 14:53
Сообщение #37


Местный
***

Группа: Участник
Сообщений: 329
Регистрация: 23-04-14
Пользователь №: 81 502



Цитата(SM @ Jan 21 2015, 14:40) *
не const, а static. Да, это мое упущение. Этому на стеке не место.


Почему static-то ?. Думаю, что компилятору будет сильно проще понять, что если int переменная объявлена как const, то выделять память для нее совсем не надо.
Кроме того, если вдруг кто-нибудь скопипастит этот код в Ц++, то следует ожидать некоторых сюрпризов:

static переменные внутри функций Ц++ инициализирует _первом_ входе управления в область видимости этой переменной.
http://stackoverflow.com/questions/55510/w...ted-initialized

То есть для Ц++ память будет выделена и переменная будет инициализирована при первом вызове Foo.
void Foo()
{
static int A = 13;
<use A>
}

думаю, что тут память вообще не будет выделяьтся
void Foo()
{
const int A = 13;
static const int B=4;
<use A, B>
}



Цитата(Jenya7 @ Jan 21 2015, 14:50) *
эээ...я тут вспомнил что у меня атолик - фри версия...мля...нулевая оптимизация...все мои листинги не годяться. извиняюсь товарищи.


Недаром, один из отцов-основателей сказал: "premature opimisation is a root of all evil"

Сообщение отредактировал CrimsonPig - Jan 21 2015, 14:53
Go to the top of the page
 
+Quote Post
SM
сообщение Jan 21 2015, 15:02
Сообщение #38


Гуру
******

Группа: Свой
Сообщений: 7 946
Регистрация: 25-02-05
Из: Moscow, Russia
Пользователь №: 2 881



Цитата(CrimsonPig @ Jan 21 2015, 17:53) *
Почему static-то

Потому, что любые переменные, не объявленные статическими, но объявленные внутри функции, располагаются на стеке, независимо от того, const они, или нет. И инициализируются динамически после вызова функции. Се ля ви, так сказать.


-------------
для ТС:

А вот Вам Ваш код, тем же компилятором, с той же оптимизацией. Сравнивайте с 15-ю инструкциями.

CODE

_Reverse:
;* --------------------------------------------------------------------------*
SUB A2, A1, #1 ; |94|
STMFD SP!, {V1, V2, V3, LR}
LDRB A3, [A2, #1]! ; |96|
.dwpsn file "C:/CCStudio_v3.3/tms470_4.6.2/include/string.h",line 96,column 0,is_stmt
MVN V9, #0 ; |93|
;* --------------------------------------------------------------------------*
;* BEGIN LOOP ||$C$L1||
;*
;* Loop source line : 96
;* Loop closing brace source line : 96
;* Known Minimum Trip Count : 1
;* Known Maximum Trip Count : 4294967295
;* Known Max Trip Count Factor : 1
;* --------------------------------------------------------------------------*
||$C$L1||:
$C$DW$L$_Reverse$2$B:
CMP A3, #0 ; |96|
LDRNEB A3, [A2, #1]! ; |96|
ADD V9, V9, #1 ; |96|
BNE ||$C$L1|| ; |96|
; BRANCHCC OCCURS {||$C$L1||} ; |96|
$C$DW$L$_Reverse$2$E:
;* --------------------------------------------------------------------------*
SUBS A3, V9, #1 ; |97|
LDMLEFD SP!, {V1, V2, V3, PC}
; BRANCHCC OCCURS {[SP, #0]}
;* --------------------------------------------------------------------------*
ADD V3, V9, V9, LSR #31 ; |36|
CMP V9, #4 ; |36|
MOV A4, V3, ASR #2 ; |36|
MOV LR, #0 ; |34|
MOV V9, A1
BLT ||$C$L3|| ; |36|
; BRANCHCC OCCURS {||$C$L3||} ; |36|
;* --------------------------------------------------------------------------*
ADD A2, A3, V9
LDRB V1, [A2, #0] ; |37|
.dwpsn file "ccs.c",line 34,column 0,is_stmt
LDRB V2, [V9, #0] ; |34|
;* --------------------------------------------------------------------------*
;* BEGIN LOOP ||$C$L2||
;*
;* Loop source line : 34
;* Loop closing brace source line : 39
;* Loop Unroll Multiple : 2x
;* Known Minimum Trip Count : 1
;* Known Maximum Trip Count : 536870911
;* Known Max Trip Count Factor : 1
;* --------------------------------------------------------------------------*
||$C$L2||:
$C$DW$L$_Reverse$6$B:
.dwpsn file "ccs.c",line 35,column 0,is_stmt
STRB V1, [V9], #1 ; |37|
STRB V2, [A2], #-1 ; |38|
LDRB V1, [A2, #0] ; |37|
LDRB V2, [V9, #0] ; |36|
SUBS A4, A4, #1 ; |34|
STRB V1, [V9], #1 ; |37|
STRB V2, [A2], #-1 ; |38|
LDRNEB V1, [A2, #0] ; |37|
LDRNEB V2, [V9, #0] ; |34|
ADD LR, LR, #2 ; |36|
SUB A3, A3, #2 ; |37|
.dwpsn file "ccs.c",line 39,column 0,is_stmt
BNE ||$C$L2|| ; |34|
; BRANCHCC OCCURS {||$C$L2||} ; |34|
$C$DW$L$_Reverse$6$E:
;* --------------------------------------------------------------------------*
||$C$L3||:
TST V3, #2
LDRNEB V9, [A1, +A3] ; |37|
LDMEQFD SP!, {V1, V2, V3, PC}
; BRANCHCC OCCURS {[SP, #0]}
;* --------------------------------------------------------------------------*
; Peeled loop iterations for unrolled loop:
LDRB A2, [A1, +LR] ; |36|
STRB V9, [A1, +LR] ; |37|
STRB A2, [A1, +A3] ; |38|
.dwpsn file "ccs.c",line 41,column 1,is_stmt
$C$DW$3 .dwtag DW_TAG_TI_branch
.dwattr $C$DW$3, DW_AT_low_pc(0x00)
.dwattr $C$DW$3, DW_AT_TI_return
LDMFD SP!, {V1, V2, V3, PC}
; BRANCH OCCURS {[SP, #0]}



CODE

_ItoA1:
;* --------------------------------------------------------------------------*
STMFD SP!, {V1, V2, V3, LR}
LDR A3, $C$CON1 ; |48|
.dwpsn file "ccs.c",line 46,column 0,is_stmt
MOV A4, A2
;* --------------------------------------------------------------------------*
;* BEGIN LOOP ||$C$L4||
;*
;* Loop source line : 46
;* Loop closing brace source line : 49
;* Known Minimum Trip Count : 1
;* Known Maximum Trip Count : 4294967295
;* Known Max Trip Count Factor : 1
;* --------------------------------------------------------------------------*
||$C$L4||:
$C$DW$L$_ItoA1$2$B:
.dwpsn file "ccs.c",line 47,column 0,is_stmt
UMULL LR, V9, A3, A1 ; |48|
MOV V9, V9, LSR #3 ; |48|
SUB A1, A1, V9, LSL #3 ; |48|
SUB A1, A1, V9, LSL #1 ; |48|
ADD LR, A1, #48 ; |48|
MOVS A1, V9 ; |50|
STRB LR, [A4], #1 ; |48|
MVNEQ V9, #0 ; |93|
.dwpsn file "ccs.c",line 49,column 0,is_stmt
BNE ||$C$L4|| ; |50|
; BRANCHCC OCCURS {||$C$L4||} ; |50|
$C$DW$L$_ItoA1$2$E:
;* --------------------------------------------------------------------------*
SUB A1, A2, #1 ; |94|
.dwpsn file "C:/CCStudio_v3.3/tms470_4.6.2/include/string.h",line 96,column 0,is_stmt
LDRB A3, [A1, #1]! ; |96|
;* --------------------------------------------------------------------------*
;* BEGIN LOOP ||$C$L5||
;*
;* Loop source line : 96
;* Loop closing brace source line : 96
;* Known Minimum Trip Count : 1
;* Known Maximum Trip Count : 4294967295
;* Known Max Trip Count Factor : 1
;* --------------------------------------------------------------------------*
||$C$L5||:
$C$DW$L$_ItoA1$4$B:
CMP A3, #0 ; |96|
LDRNEB A3, [A1, #1]! ; |96|
ADD V9, V9, #1 ; |96|
BNE ||$C$L5|| ; |96|
; BRANCHCC OCCURS {||$C$L5||} ; |96|
$C$DW$L$_ItoA1$4$E:
;* --------------------------------------------------------------------------*
SUBS A3, V9, #1 ; |97|
LDMLEFD SP!, {V1, V2, V3, PC}
; BRANCHCC OCCURS {[SP, #0]}
;* --------------------------------------------------------------------------*
ADD V3, V9, V9, LSR #31 ; |36|
CMP V9, #4 ; |36|
MOV A4, V3, ASR #2 ; |36|
MOV LR, #0 ; |34|
MOV V9, A2
BLT ||$C$L7|| ; |36|
; BRANCHCC OCCURS {||$C$L7||} ; |36|
;* --------------------------------------------------------------------------*
ADD A1, A3, V9
LDRB V1, [A1, #0] ; |37|
.dwpsn file "ccs.c",line 34,column 0,is_stmt
LDRB V2, [V9, #0] ; |34|
;* --------------------------------------------------------------------------*
;* BEGIN LOOP ||$C$L6||
;*
;* Loop source line : 34
;* Loop closing brace source line : 39
;* Loop Unroll Multiple : 2x
;* Known Minimum Trip Count : 1
;* Known Maximum Trip Count : 536870911
;* Known Max Trip Count Factor : 1
;* --------------------------------------------------------------------------*
||$C$L6||:
$C$DW$L$_ItoA1$8$B:
.dwpsn file "ccs.c",line 35,column 0,is_stmt
STRB V1, [V9], #1 ; |37|
STRB V2, [A1], #-1 ; |38|
LDRB V1, [A1, #0] ; |37|
LDRB V2, [V9, #0] ; |36|
SUBS A4, A4, #1 ; |34|
STRB V1, [V9], #1 ; |37|
STRB V2, [A1], #-1 ; |38|
LDRNEB V1, [A1, #0] ; |37|
LDRNEB V2, [V9, #0] ; |34|
ADD LR, LR, #2 ; |36|
SUB A3, A3, #2 ; |37|
.dwpsn file "ccs.c",line 39,column 0,is_stmt
BNE ||$C$L6|| ; |34|
; BRANCHCC OCCURS {||$C$L6||} ; |34|
$C$DW$L$_ItoA1$8$E:
;* --------------------------------------------------------------------------*
||$C$L7||:
TST V3, #2
LDRNEB V9, [A2, +A3] ; |37|
LDMEQFD SP!, {V1, V2, V3, PC}
; BRANCHCC OCCURS {[SP, #0]}
;* --------------------------------------------------------------------------*
; Peeled loop iterations for unrolled loop:
LDRB A1, [A2, +LR] ; |36|
STRB V9, [A2, +LR] ; |37|
STRB A1, [A2, +A3] ; |38|
.dwpsn file "ccs.c",line 53,column 1,is_stmt
$C$DW$11 .dwtag DW_TAG_TI_branch
.dwattr $C$DW$11, DW_AT_low_pc(0x00)
.dwattr $C$DW$11, DW_AT_TI_return
LDMFD SP!, {V1, V2, V3, PC}
; BRANCH OCCURS {[SP, #0]}
Go to the top of the page
 
+Quote Post
CrimsonPig
сообщение Jan 21 2015, 15:09
Сообщение #39


Местный
***

Группа: Участник
Сообщений: 329
Регистрация: 23-04-14
Пользователь №: 81 502



Цитата(SM @ Jan 21 2015, 15:02) *
Потому, что любые переменные, не объявленные статическими, но объявленные внутри функции, располагаются на стеке, независимо от того, const они, или нет. И инициализируются динамически после вызова функции. Се ля ви, так сказать.


Припадаем к источникам:
http://stackoverflow.com/questions/93039/w...s-stored-in-c-c

Какая разница с т.з. потребляемой RAM, если компилятор решит разместить automatic variable на стеке или такую же static в .DATA или .BSS ?
В то время как const имеет больше шансов стать просто числом (по аналогии с "#define A (23)" )
Go to the top of the page
 
+Quote Post
SM
сообщение Jan 21 2015, 15:19
Сообщение #40


Гуру
******

Группа: Свой
Сообщений: 7 946
Регистрация: 25-02-05
Из: Moscow, Russia
Пользователь №: 2 881



Цитата(CrimsonPig @ Jan 21 2015, 18:09) *
Какая разница


Две большие разницы. На стек надо каждый раз при входе в фунцию предопределенные данные копировать. В .data они попадают на этапе загрузки программы один раз. А в .const (или .rodata), так они, вообще могут браться прямо из флеш-памяти прямой адресацией туда. Таким образом, имеем оверхед на копирование массива констант в стек, если без static, но с const. А вот с static, и, все равно, с const или без, не имеем этого оверхеда. Причем, проверено совсем недавно тут - http://electronix.ru/forum/index.php?showtopic=125422

Цитата(CrimsonPig @ Jan 21 2015, 17:53) *
В то время как const имеет больше шансов стать просто числом (по аналогии с "#define A (23)" )

Давайте ближе к теме, в сторону не уходить. У нас массив, по которому проводится доступ по индексу. А не просто число.
Go to the top of the page
 
+Quote Post
Jenya7
сообщение Jan 21 2015, 15:46
Сообщение #41


Профессионал
*****

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



Цитата(CrimsonPig @ Jan 21 2015, 20:53) *
Недаром, один из отцов-основателей сказал: "premature opimisation is a root of all evil"


ничего себе premature. три месяца пишу на фри версии. sm.gif
Go to the top of the page
 
+Quote Post

3 страниц V  < 1 2 3
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 23rd July 2025 - 16:00
Рейтинг@Mail.ru


Страница сгенерированна за 0.01695 секунд с 7
ELECTRONIX ©2004-2016