ЗАО «ЗЭО»
Техническая поддержка пользователей => Тион, Тион-Про, Тион-Про v2, Сириус => Тема начата: nibbler от 30 Июля, 2009, 11:21:34
-
Ситуация такая:
Есть следующая программка:
int start_C()
{
int i, count = 1000;
long *start = (long *) (0x00800000);
long *stop = (long *) (0x00896000); //stop-start = 640*480*2
long *ind;
for(i = 0; i < count; i++){
ind = start;
do{
*(ind++) = 0xABCDEF01;
}while(ind < stop);
}
return count;
}
Компилю её с помощью 3.2.1-elf c флагом -O2.
В итоге получаю бинарник, результат дизассемблирования:
c0008000 <_entry>:
c0008000: ea000000 b c0008008 <start_C>
c0008004 <set_pc>:
c0008004: e1a0f000 mov pc, r0
c0008008 <start_C>:
c0008008: e3a02889 mov r2, #8978432 ; 0x890000
c000800c: e59f1028 ldr r1, [pc, #40] ; c000803c <start_C+0x34>
c0008010: e2822a06 add r2, r2, #24576 ; 0x6000
c0008014: e3a00000 mov r0, #0 ; 0x0
c0008018: e3a03502 mov r3, #8388608 ; 0x800000
;
;следующие три инструкции должны выполниться 640*480/2*1000 = 153 600 000 раз
c000801c: e4831004 str r1, [r3], #4
c0008020: e1530002 cmp r3, r2
c0008024: 3afffffc bcc c000801c <start_C+0x14>
;
c0008028: e2800001 add r0, r0, #1 ; 0x1
c000802c: e3500ffa cmp r0, #1000 ; 0x3e8
c0008030: a3a00ffa movge r0, #1000 ; 0x3e8
c0008034: a1a0f00e movge pc, lr
c0008038: eafffff6 b c0008018 <start_C+0x10>
c000803c: abcdef01 blge bf383c48 <_entry-0xc843b8>
Эту программку запускаю в u-boot:
tftp 0 mem.bin
go 0
И работает она около 20-ти секунд.
В результате нехитрых вычислений получается производительность при работе с памятью ок. 20 MIPS.
Вопросы:
1) это верно?
2) почему так медленно?
3) можно ли быстрее заполнить массив в памяти?
-
В U-Boot не включен D-кэш и не будет включен.
-
Под линуксом быстрее залить память не получается. Может какую опцию в ядре надо включить?
-
Код для Linux такой же оставили?!
-
вот такой код на С++
int size = 320*480;
long buff[size];
int count = 1000;
long color = 0x01234567;
for(int i = 0; i < count; i++){
for(int ind = 0; ind < size; ind++){
buff[ind] = color;
}
}
скомпиленный с опциями -mcpu=arm920t -mtune=arm920t -O2
всё равно работает около 20 секунд
Вот такой карявый вариант работает чуть быстрее: 12 сек.
//main.c
...
extern void fillmem(long * start, long * end, long color, long color1);
...
@fillmem.s
...
.L2:
stmia r0!, {r2, r3}
cmp r0, r1
bne .L2
mov pc, lr
...
Использование инструкции stm не решает проблему. Память заливается и копируется слишком медленно.
-
> buff[ind] = color;
1. С указателями было бы быстрее.
2. В U-Boot вы записывали 1000 раз по 0x96000 байт (0x96000/4 слов) за ~20 с.
В Linux это занимает 11 c.
int main (void)
{
int size = 0x96000/sizeof(long);
long buff[size];
int count = 1000;
long color = 0x01234567;
int ind, i;
long *p;
for(i = 0; i < count; i++) {
p = buff;
for(ind = 0; ind < size; ind++) {
*(p++) = color;
}
}
printf ("total %d\n", size*count);
}
-
2. В U-Boot вы записывали 1000 раз по 0x96000 байт (0x96000/4 слов) за ~20 с.
В Linux это занимает 11 c.
Вот что у меня получилось с этим тестом в Linux-е:
/ # time tstftdi -t
total 153600000
real 0m 6.12s
user 0m 6.11s
sys 0m 0.00s
/ # uname -a
Linux corr 2.6.30-tion #1 PREEMPT Wed Jul 29 15:02:36 MSD 2009 armv4tl unknown
/ # cat /proc/cpuinfo
Processor : ARM920T rev 0 (v4l)
BogoMIPS : 99.53
Features : swp half thumb crunch
CPU implementer : 0x41
CPU architecture: 4T
CPU variant : 0x1
CPU part : 0x920
CPU revision : 0
Hardware : ZAO ZEO TION9315 SBC module
Revision : 0000
Serial : 0000000000000000
/ #
-
Компилятор, флаги?
-
/usr/local/arm/4.1.1-920t/bin/arm-linux-gcc -Wall -mcpu=arm920t -mtune=arm920t -O3 test.c
/ # time ./a.out
total 153600000
real 0m 10.54s
user 0m 10.52s
sys 0m 0.01s
/ # uname -a
Linux tion-pro 2.6.20.4 #1 PREEMPT Fri Jul 31 13:23:36 EEST 2009 armv4tl unknown
/ # cat /proc/cpuinfo
Processor : ARM920T rev 0 (v4l)
BogoMIPS : 99.73
Features : swp half thumb crunch
CPU implementer : 0x41
CPU architecture: 4T
CPU variant : 0x1
CPU part : 0x920
CPU revision : 0
Cache type : write-back
Cache clean : cp15 c7 ops
Cache lockdown : format A
Cache format : Harvard
I size : 16384
I assoc : 64
I line length : 32
I sets : 8
D size : 16384
D assoc : 64
D line length : 32
D sets : 8
Hardware : Cirrus Logic EDB9312 Evaluation Board
Revision : 0000
Serial : 0000000000000000
-
А вот другой результат
/usr/test # time ./a.out
total 153600000
real 0m 19.27s
user 0m 19.24s
sys 0m 0.03s
в то время как включен 640*480 экран
-
Компилятор, флаги?
./arm-linux-uclibcgnueabi-gcc -v
Используются внутренние спецификации.
Целевая архитектура: arm-linux-uclibcgnueabi
Параметры конфигурации: /home/CRUS/crunch-tools-1.4.3/build/gcc-4.1.2/configure --target=arm-linux-uclibcgnueabi --prefix=/home/CRUS/crunch-tools-1.4.3/eabi/ep93xx-eabi-d1 --enable-languages=c,c++ --disable-multilib --disable-libmudflap --disable-libssp
Модель многопотоковости: posix
gcc версия 4.1.2
это из packages/Makefile.in
TARGET_CROSS_CC='$(TARGET_CROSS)gcc -mcpu=ep9312 -mfpu=maverick -mfloat-abi=softfp -mfix-crunch-d1'
TARGET_CROSS_CXX='$(TARGET_CROSS)g++ -mcpu=ep9312 -mfpu=maverick -mfloat-abi=softfp -mfix-crunch-d1'
оптимизация -O2
дисплей включен 640х480
-
Меньше 10 с на 2.6.20 у меня не получается.
faa, не затруднит прислать/выложить собранный статически тест, который
выполняется 6 с?
-
Меньше 10 с на 2.6.20 у меня не получается.
faa, не затруднит прислать/выложить собранный статически тест, который
выполняется 6 с?
В понедельник постараюсь сделать.
Ну и на старом (2.6.20.4 или 2.6.21.5) ядре попробую (вроде были в закромах).
-
Я как раз хотел на 2.6.20 посмотреть.
-
Меньше 10 с на 2.6.20 у меня не получается.
faa, не затруднит прислать/выложить собранный статически тест, который
выполняется 6 с?
Выложил ftp.ntcsm.ru/pub/tion9315/tstftdi (ftp://ftp.ntcsm.ru/pub/tion9315/tstftdi).
Запускать tstftdi -t.
#file tstftdi
tstftdi: ELF 32-bit LSB executable, ARM, version 1 (SYSV), statically linked, stripped
-
спасибо, faa, за участие.
/usr/test # time ./tstftdi -t
total 153600000
real 0m 20.83s
user 0m 20.77s
sys 0m 0.03s
Значит дело в ядре ...
Да, с чего всё началось. Мне один товарищ сказал, что у него на windows ce такой же тест меньше 4-х секунд идёт.
-
На нём тоже 10 с (без sticky-бита даже 20 с, но не важно)
-
faa, если не затруднит, дайте .config для ядра 2.6.30, может, что из подсистем выключено?
-
asv, а можно глупый вопрос: при чём тут sticky-бит?
-
Код не выгружается и второй раз работает быстрее.
-
Вы имеете в виду флаг режима доступа (он же sticky-bit, он же S_ISVTX ) на самом исполняемом файле на target машине? Тот который устанавливается коммандой chmod -t ?
Если да то дело не в нём, или не только в нём, потому что у меня он ни на что не влияет.
-
Да, его. У меня КФС была на CF и заметно, что секунд через 10 после запуска программы мигал светодиод.
Возникла мысль о sticky. Опыт подтверждает.
-
faa, если не затруднит, дайте .config для ядра 2.6.30, может, что из подсистем выключено?
config в аттаче.
КФС на nfs.
-
С этим .config и 2.6.31-rc1-gf6430a9 тоже 10 с.
faa, что у вас за загрузчик?
-
С этим .config и 2.6.31-rc1-gf6430a9 тоже 10 с.
faa, что у вас за загрузчик?
Скорее всего RedBoot... т.к. думаю на u-boot он еще не перешел :)
Ядро 2.6.21.5. busybox 1.12.1.
redboot. На uboot еще не перелез.
тулчейн crunch-tools-1.4.3 eabi: gcc 4.1.2, binutils 2.18, uclibc 0.9.29
-
Ядро уже поменял...
-
Ядро уже поменял...
Угу. на 2.6.30.
2.6.21.5 с нфс как-то неуверенно работает :)
uclibc вправленная - непатченная 0.9.29 не дает mmap дальше 7fffffff делать. патч я кидал в гугле-группу.
ЗЫ: тест через указатели сделан. Через индексы медленнее, но не на много.
-
/usr/test # time ./test-static
real 0m 10.87s
user 0m 10.87s
sys 0m 0.01s
Ураааа!!!
На очереди новый барьер: 6 сек.
-
С Redboot и 2.6.20.21 получается 6.95 с, надо пересмотреть инициализацию в U-Boot.
-
Ураааа!!!
На очереди новый барьер: 6 сек.
Что изменили?
-
С Redboot и 2.6.20.21 получается 6.95 с, надо пересмотреть инициализацию в U-Boot.
ИМХО, времянки контроллера сдрам надо смотреть, если это не эффект от eabi и оптимизации gcc.
ЗЫ: Шину SMC я разгонял - эффект поразительный :)
-
ХАха рано обрадовался.
Что изменили?
Забыл дисплей включить. Таким образом:
U-Boot 1.3.3-svn200
Linux tion-pro 2.6.20.4 #1 PREEMPT Wed Aug 5 12:44:09 EEST 2009 armv4tl unknown (скомпилен gcc4.2.2)
arm-linux-gcc -v
Reading specs from /home/nibbler/eldk/usr/bin/../lib/gcc/arm-linux-gnueabi/4.2.2/specs
Target: arm-linux-gnueabi
Configured with: /opt/eldk/build/arm-2008-11-24/work/usr/src/denx/BUILD/crosstool-0.43/build/gcc-4.2.2-glibc-20070515T2025-eldk/arm-linux-gnueabi/gcc-4.2.2/configure --target=arm-linux-gnueabi --host=i686-host_pc-linux-gnu --prefix=/var/tmp/eldk.ywMqKk/usr/crosstool/gcc-4.2.2-glibc-20070515T2025-eldk/arm-linux-gnueabi --disable-hosted-libstdcxx --with-headers=/var/tmp/eldk.ywMqKk/usr/crosstool/gcc-4.2.2-glibc-20070515T2025-eldk/arm-linux-gnueabi/arm-linux-gnueabi/include --with-local-prefix=/var/tmp/eldk.ywMqKk/usr/crosstool/gcc-4.2.2-glibc-20070515T2025-eldk/arm-linux-gnueabi/arm-linux-gnueabi --disable-nls --enable-threads=posix --enable-symvers=gnu --enable-__cxa_atexit --enable-languages=c,c++,java --enable-shared --enable-c99 --enable-long-long --without-x
Thread model: posix
gcc version 4.2.2
Всё осталось по-прежнему: 20 сек.
:(
1) ядро 2.6.20.21 с новым патчем linux-2.6.20.21_tion_svn618_200907131105 не компилится
CC drivers/mtd/chips/map_ram.o
drivers/mtd/chips/map_ram.c: In function 'map_ram_probe':
drivers/mtd/chips/map_ram.c:69: error: 'struct mtd_info' has no member named 'get_unmapped_area'
make[3]: *** [drivers/mtd/chips/map_ram.o] Ошибка 1
make[2]: *** [drivers/mtd/chips] Ошибка 2
make[1]: *** [drivers/mtd] Ошибка 2
make: *** [drivers] Ошибка 2
2) надо пересмотреть инициализацию в U-Boot.
Где её можно посмотреть? В исходниках?
3) ЗЫ: Шину SMC я разгонял - эффект поразительный
А это каким образом?
-
надо пересмотреть инициализацию в U-Boot.
Где её можно посмотреть? В исходниках?
Именно там :)
Смотрел вчера долго на redboot и uboot - по аппаратной части ничего, кроме как разной частоты рефреша у сдрам, не высмотрел.
ЗЫ: Шину SMC я разгонял - эффект поразительный
А это каким образом?
У меня там FPGA висит.
По умолчанию стоит максимальная длительность RD и WR. С ней и программируем FPGA.
/* set up CS7, 32 bit data bus, idcy 2, wst1 = 0x1ff, rble enabled, wst2 = 0x1ff */
writel(0x2000ffe1, EP93XX_SMC_SMCBCR7);
А потом:
/* set up CS7, 32 bit data bus, idcy 2, wst1 = 0x100, rble enabled, wst2 = 0x11 */
writel(0x20001C81, EP93XX_SMC_SMCBCR7);
-
> ХАха рано обрадовался.
> Всё осталось по-прежнему: 20 сек.
У меня если экран отключен, то 10 с, если включен, то 20.
Включить
echo 0 > /sys/class/graphics/fb0/blank
Выключить
echo 1 > /sys/class/graphics/fb0/blank
> 1) ядро 2.6.20.21 с новым патчем linux-2.6.20.21_tion_svn618_200907131105 не компилится
> CC drivers/mtd/chips/map_ram.o
> drivers/mtd/chips/map_ram.c: In function 'map_ram_probe':
> drivers/mtd/chips/map_ram.c:69: error: 'struct mtd_info' has no member named 'get_unmapped_area'
> make[3]: *** [drivers/mtd/chips/map_ram.o] Ошибка 1
> make[2]: *** [drivers/mtd/chips] Ошибка 2
> make[1]: *** [drivers/mtd] Ошибка 2
> make: *** [drivers] Ошибка 2
С каким defconfig?
> 2) Цитировать
> надо пересмотреть инициализацию в U-Boot.
> Где её можно посмотреть? В исходниках?
Да, но в основном, то что в патче. Я пока ничего не увидел из сравнения
инициализации Redboot и U-Boot. Сейчас думаю посмотреть на состояние
регистров контроллера памяти для обоих после загрузки.
-
c tion_defconfig
А где взять redBoot ?
-
Redboot есть в Crater.
Между Redboot и U-Boot разница есть, надо ещё раз смотреть инициализацию:
R: 0x80060004 0x80000000 GlConfig: Global Configurati
U: 0x80060004 0x80000020 GlConfig: Global Configurati
R: 0x80060008 0x2F0 RefrshTimr: Refresh Timer
U: 0x80060008 0x23 RefrshTimr: Refresh Timer
-
Redboot есть в Crater.
Между Redboot и U-Boot разница есть, надо ещё раз смотреть инициализацию:
R: 0x80060004 0x80000000 GlConfig: Global Configurati
U: 0x80060004 0x80000020 GlConfig: Global Configurati
R: 0x80060008 0x2F0 RefrshTimr: Refresh Timer
U: 0x80060008 0x23 RefrshTimr: Refresh Timer
R: Частота регенерации (refresh) да загрузки ядра - 0x2f0, после загрузки ядра - 0x2f0.
Можно накрутить до 0x30d - максимум, что можно для такой памяти. (64мсек/8192 = 7,81мксек ~ 7810/Thclk = 781).
Но на скорость это почти не повлияло :)
Попробовал поставить 0x23 - результаты привожу:
/ # devmem 0x80060008
/dev/mem opened.
Memory mapped at address 0x40006000.
Value at address 0x80060008 (0x40006008): 0x2F0
/ # time tstftdi -t
total 153600000
real 0m 6.12s
user 0m 6.09s
sys 0m 0.00s
/ # devmem 0x80060008 w 0x30d
/dev/mem opened.
Memory mapped at address 0x40006000.
Written 0x30D; readback 0x30D
/ # time tstftdi -t
total 153600000
real 0m 6.12s
user 0m 6.09s
sys 0m 0.01s
/ # devmem 0x80060008 w 0x23
/dev/mem opened.
Memory mapped at address 0x40006000.
Written 0x23; readback 0x23
/ # time tstftdi -t
total 153600000
real 0m 19.32s
user 0m 19.28s
sys 0m 0.02s
/ #
ЗЫ: в uboot-е 0 надо дописать к 0x23
/ # devmem 0x80060008 w 0x230
/dev/mem opened.
Memory mapped at address 0x40006000.
Written 0x230; readback 0x230
/ # time tstftdi -t
total 153600000
real 0m 6.19s
user 0m 6.17s
sys 0m 0.00s
/ #
-
уфф
поставил в u-boot 0x2f0 и всё стало супер, а именно: теперь с любыми ядрами скомпиленными любыми компиляторами с почти любыми флагами результат теста 6 сек.
Всем огромное спасибо.
И ещё test.c, который в аттаче работает 4 сек!
-
Поправил defconfig'и в svn722, теперь должно собираться.
1) ядро 2.6.20.21 с новым патчем linux-2.6.20.21_tion_svn618_200907131105 не компилится
CC drivers/mtd/chips/map_ram.o
drivers/mtd/chips/map_ram.c: In function 'map_ram_probe':
drivers/mtd/chips/map_ram.c:69: error: 'struct mtd_info' has no member named 'get_unmapped_area'
make[3]: *** [drivers/mtd/chips/map_ram.o] Ошибка 1
make[2]: *** [drivers/mtd/chips] Ошибка 2
make[1]: *** [drivers/mtd] Ошибка 2
make: *** [drivers] Ошибка 2