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

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> Матрица 8х8 - как заменить столбцы строками ?, требуется БЫСТРЫЙ алгоритм обработки
french
сообщение Mar 10 2008, 12:36
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 34
Регистрация: 21-09-04
Пользователь №: 688



Реальная задача для контроллера Мega128 (CVAVR):
есть две матрицы 8х8 бит - два массива по 8 байт
Код
// здесь какждый байт массива представляет собой столбец матрицы
char Vbuf[1][8] = {... типа данные};
// а этом случае каждый байт массива - это строка
char Hbuf[8][1] = {... типа данные};

в общем данные хранятся примерно так ...
Vbuf[1][8];                 Hbuf[8][1];

0  0  0  0  0  0  0  0     0 1 2 3 4 5 6 7
1  1  1  1  1  1  1  1     0 1 2 3 4 5 6 7
2  2  2  2  2  2  2  2     0 1 2 3 4 5 6 7
3  3  3  3  3  3  3  3     0 1 2 3 4 5 6 7
4  4  4  4  4  4  4  4     0 1 2 3 4 5 6 7
5  5  5  5  5  5  5  5     0 1 2 3 4 5 6 7
6  6  6  6  6  6  6  6     0 1 2 3 4 5 6 7
7  7  7  7  7  7  7  7     0 1 2 3 4 5 6 7

т.е. первый байт Vbuf представляет собой  0-ые биты каждого байта Hbuf
второй байт Vbuf представляет собой 1-ые биты каждого байта Hbuf и т.д....

Требуется преобразовать матрицу Vbuf в Hbuf.

Простейшее решение - побитовое копирование.
В это случае контроллер должен будет сделать (8х8)*(команды извлечения бита + команды копирования бита + куча команд для формиро циклов) операций. В итоге получается АЦКАЯ работа.
В моем случае таких матриц к примеру 80 и обработка занимает порядка 50мс.

Хотелось бы услышать дельные советы бывалых программеров о том как оптимизировать алгоритм (мега тактируестя 20МГц и менять ее на что-то более мощное не возможности). Может стоит по другому организовать хранение данных или есть типовые алгоритмы. Буду рад услышать любой совет !!!!
Go to the top of the page
 
+Quote Post
Rst7
сообщение Mar 10 2008, 13:01
Сообщение #2


Йа моск ;)
******

Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610



Алгоритм то есть. Не факт, правда, что на AVR он будет быстрее чем копирование битов, хотя можно попробовать. Готового исходника у меня под рукой нет, но основную идею постараюсь обрисовать.

Есть 8 байт, сперва необходимо провернуть по биту
Код
76543210 - 1й байт
HGFEDCBA - 2й байт
76543210 - 3й байт
HGFEDCBA - 4й байт
76543210 - 5й байт
HGFEDCBA - 6й байт
76543210 - 7й байт
HGFEDCBA - 8й байт

нужно изготовить
Код
6G4E2C0A
7H5F3D1B
6G4E2C0A
7H5F3D1B
6G4E2C0A
7H5F3D1B
6G4E2C0A
7H5F3D1B


Следующая стадия - проворот по 2 бита, следующая - по четыре.
Обрисую результат стадии поворота по 2 бита (участвуют по 4 байта), одна цифра - 2 бита:
Код
3210
7654
DCBA
HGFE

->
Код
2C0A
6G4E
3D1B
7H5F


и последний поворот по 4 бита
Код
10
32

->
Код
02
13


--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
Go to the top of the page
 
+Quote Post
vet
сообщение Mar 10 2008, 13:03
Сообщение #3


Знающий
****

Группа: Свой
Сообщений: 550
Регистрация: 16-06-04
Из: Казань
Пользователь №: 32



а цель какова? может, оно и не нужно вовсе, такое вот преобразование?


--------------------
Главная линия этого опуса ясна мне насквозь!
Go to the top of the page
 
+Quote Post
=GM=
сообщение Mar 10 2008, 14:35
Сообщение #4


Ambidexter
*****

Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282



Цитата(french @ Mar 10 2008, 12:36) *
Реальная задача для контроллера Мega128 (CVAVR): есть две матрицы 8х8 бит - два массива по 8 байт
...
т.е. первый байт Vbuf представляет собой 0-ые биты каждого байта Hbuf, второй байт Vbuf представляет собой 1-ые биты каждого байта Hbuf и т.д. Требуется преобразовать матрицу Vbuf в Hbuf.

Простейшее решение - побитовое копирование.
В это случае контроллер должен будет сделать (8х8)*(команды извлечения бита + команды копирования бита + куча команд для формиро циклов) операций. В итоге получается АЦКАЯ работа.
В моем случае таких матриц к примеру 80 и обработка занимает порядка 50мс.

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

Разместите 8 байт вашего Vbuf в регистрах r0-r7 и делайте побитное копирование, например, вызывая такую подпрограмму:
Код
getHbyte:
   ror   r0
   ror   r8
   ror   r1
   ror   r8
   ror   r2
   ror   r8
   ror   r3
   ror   r8
   ror   r4
   ror   r8
   ror   r5
   ror   r8
   ror   r6
   ror   r8
   ror   r7
   ror   r8  ;готов n-й байт Hbuf
   ret
забираете готовый байт и повторяете ещё 7 раз. На один байт уйдёт 23МЦ, на одну конвертацию вгрубе уйдёт всего 8*23*0.05=9.2 мкс, на 80 уйдёт 80*9.2=736 мкс, откуда 50 мс?


--------------------
Делай сразу хорошо, плохо само получится
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Mar 10 2008, 20:46
Сообщение #5


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



А зачем её поворачивать вообще?

При обращении к одной - используйте координаты X,Y, а для другой Y,X.
Go to the top of the page
 
+Quote Post
kv_addr
сообщение Mar 10 2008, 21:02
Сообщение #6


Местный
***

Группа: Свой
Сообщений: 208
Регистрация: 6-07-04
Из: Полтава
Пользователь №: 279



Транспонирование матрицы битов:
Код
   b0 b1 b2 b3 b4 b5 b6 b7      b0 b1 b2 b3 b4 b5 b6 b7
r0 00 01 02 03 04 05 06 07  r8  00 10 20 30 40 50 60 70
r1 10 11 12 13 14 15 16 17  r9  01 11 21 31 41 51 60 71
r2 20 21 22 23 24 25 26 27  r10 02 12 22 32 42 52 62 72
r3 30 31 32 33 34 35 36 37  r11 03 13 23 33 43 53 63 73
r4 40 41 42 43 44 45 46 47  r12 04 14 24 34 44 54 64 74
r5 50 51 52 53 54 55 56 57  r13 05 15 25 35 45 55 65 75
r6 60 61 62 63 64 65 66 67  r14 06 16 26 36 46 56 66 76
r7 70 71 72 73 74 75 76 77  r15 07 17 27 37 47 57 67 77

Простой вариант "в лоб".
Исходная помещается в r0-r7, результирующая получается в r8-r15:
Код
    movw r8,r0
    mowv r10,r2
    movw r12,r4
    movw r14,r6
    bst r0,1
    bld r9,0  // из 01 перенесено в 10 другой матрицы
    bst r1,0
    bld r8,1  // из 10 перенесено в 01 другой матрицы
    ...
    bst r6,7
    bld r15,6 // из 67 перенесено в 76 другой матрицы
    bst r7,6
    bld r14,7 // из 76 перенесено в 67 другой матрицы

Всего необходимо 28 взаимных пересылок, что в результате занимает 28х4=112 тактов. Плюс 4 такта копирования регистровых пар, получается 116 тактов. Итого транспонирование матрицы битов занимает по времени 5,8 мкс. Для 80 матриц - 464 мкс, с накладыми расходами пусть будет ~0,5 мс, т.е. в 100 раз быстрее, чем у Вас получилось.

PS: Сейчас не вспомню, но существует более быстый способ транспонирования, дающий экономию еще около 20% времени.
Go to the top of the page
 
+Quote Post
vetal
сообщение Mar 10 2008, 21:39
Сообщение #7


Гуру
******

Группа: Модераторы
Сообщений: 2 095
Регистрация: 27-08-04
Из: Россия, СПб
Пользователь №: 553



Цитата
А зачем её поворачивать вообще?

При обращении к одной - используйте координаты X,Y, а для другой Y,X.

+1 smile.gif
Код
char buf[8][8] = {... типа данные};
#define Vbuf(x,y) buf[x][y]
#define Hbuf(x,y) buf[y][x]
Go to the top of the page
 
+Quote Post
kv_addr
сообщение Mar 10 2008, 22:26
Сообщение #8


Местный
***

Группа: Свой
Сообщений: 208
Регистрация: 6-07-04
Из: Полтава
Пользователь №: 279



Цитата(vetal @ Mar 11 2008, 01:39) *
+1 smile.gif
Код
char buf[8][8] = {... типа данные};
#define Vbuf(x,y) buf[x][y]
#define Hbuf(x,y) buf[y][x]

sad.gif По условию задачи было не 8х8 байт, а 8х8 бит. Вроде так. 07.gif
Go to the top of the page
 
+Quote Post
Непомнящий Евген...
сообщение Mar 11 2008, 07:31
Сообщение #9


Знающий
****

Группа: Свой
Сообщений: 771
Регистрация: 16-07-07
Из: Волгодонск
Пользователь №: 29 153



таблицу соответствия можно использовать - будет быстро, но надо 256 байт памяти.
Go to the top of the page
 
+Quote Post
Rst7
сообщение Mar 11 2008, 07:34
Сообщение #10


Йа моск ;)
******

Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610



Цитата
таблицу соответствия можно использовать - будет быстро, но надо 256 байт памяти.


Это простите как? Что хранить в этой таблице?


--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
Go to the top of the page
 
+Quote Post
Непомнящий Евген...
сообщение Mar 11 2008, 07:51
Сообщение #11


Знающий
****

Группа: Свой
Сообщений: 771
Регистрация: 16-07-07
Из: Волгодонск
Пользователь №: 29 153



Цитата(Rst7 @ Mar 11 2008, 10:34) *
Это простите как? Что хранить в этой таблице?

Упс, поспешил. Этот вариант не подходит.
Go to the top of the page
 
+Quote Post
Rst7
сообщение Mar 11 2008, 07:59
Сообщение #12


Йа моск ;)
******

Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610



Цитата
Упс, поспешил. Этот вариант не подходит.


Именно. Видимо, для AVR оптимальный вариант - развернутое копирование битов, варианты со сдвигами хороши для большей разрядности, например 32.


--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
Go to the top of the page
 
+Quote Post
Непомнящий Евген...
сообщение Mar 11 2008, 08:13
Сообщение #13


Знающий
****

Группа: Свой
Сообщений: 771
Регистрация: 16-07-07
Из: Волгодонск
Пользователь №: 29 153



А вариант
Код
#define TESTBIT(v, n) ( (v>>n) & 1)
char buf[8] = {... типа данные};
#define Vbuf(x,y) TESTBIT(buf[x], y)
#define Hbuf(x,y) TESTBIT(buf[y], x)

чем не устраивает?
Go to the top of the page
 
+Quote Post
french
сообщение Mar 11 2008, 09:13
Сообщение #14


Участник
*

Группа: Участник
Сообщений: 34
Регистрация: 21-09-04
Пользователь №: 688



Правильно задать вопрос - пол проблемы решить !!! Чтобы не путать уважаемою аудиторию постараюсь яснее изложить мою проблему:
Есть два массива по 8 байт (а в реале размер кратен 8)
unsigned char Vbuf[8];
unsigned char Hbuf[8];

пусть Vbuf будет таким:

12345678 - 1-й байт
ABCDEFGH - 2-й байт
87654321 - 3-й байт
abcdefgh - 4-й байт
QWERTYUI - 5-й байт
qwertyui - 6-й байт
ASDFGHJK - 7-й байт
asdfghjk - 8-й байт

надо скопировать в Hbuf так чтобы в нем
1A8aQqAa - 1-й байт
2B7bWwSs - 2-й байт
3C6cEeDd - 3-й байт
4D5dRrFf - 4-й байт
5e4eTtGg - 5-й байт
6F3fYyHh - 6-й байт
7G2gUuJj - 7-й байт
8H1hIiKk - 8-й байт

решение задачи в лоб (побитовое копирование) выглядит так:
Код
#define _HEIGHT 16    // высота экрана в строках (битах)
#define _WIDTH     4    // ширина экрана кратная 1 байту
#define _H _HEIGHT/8
#define _W _WIDTH*8

unsigned char SCREEN2[_HEIGHT][_WIDTH];    // буфер видео-памяти (G-формат)
unsigned char BUFFER [_H][_W];            // рабочий буфер видео-памяти (V-формат)
unsigned char ws_i=0, wb_i=0, hsi_bit=0, hs_i=0, hs_byte=0;
// преобразование данных из вертикального формата
// в горизонталный
for(ws_i=0; ws_i<_WIDTH; ws_i++)
{
    for(hs_i=0; hs_i<_HEIGHT; hs_i++)
    {
        if(hsi_bit > 7)    {hsi_bit=0;  hs_byte++;}
        for(wb_i=0; wb_i<8; wb_i++)
               SCREEN[hs_i][ws_i] |= (((unsigned char)BUFFER[hs_byte][(unsigned int)(wb_i+ 8*ws_i)]>>hsi_bit)<<7)>>wb_i; // собственно побитовое копирование !!!

            hsi_bit++;
     }
     hs_byte=0;
     hsi_bit=0;
}

эта штука работает, но долго !!!

Цитата
Простой вариант "в лоб".
Исходная помещается в r0-r7, результирующая получается в r8-r15:
movw r8,r0
mowv r10,r2
movw r12,r4
movw r14,r6
bst r0,1
bld r9,0 // из 01 перенесено в 10 другой матрицы
bst r1,0
bld r8,1 // из 10 перенесено в 01 другой матрицы
...
bst r6,7
bld r15,6 // из 67 перенесено в 76 другой матрицы
bst r7,6
bld r14,7 // из 76 перенесено в 67 другой матрицы

Всего необходимо 28 взаимных пересылок, что в результате занимает 28х4=112 тактов. Плюс 4 такта копирования регистровых пар, получается 116 тактов. Итого транспонирование матрицы битов занимает по времени 5,8 мкс. Для 80 матриц - 464 мкс, с накладыми расходами пусть будет ~0,5 мс, т.е. в 100 раз быстрее, чем у Вас получилось.

класс, но пишу на Си, регистры все заняты компилятором !!! можно конечно сохранять их значения а потом восстанавливать, но 16 регистров.... помоему не реально.
Go to the top of the page
 
+Quote Post
Rst7
сообщение Mar 11 2008, 10:11
Сообщение #15


Йа моск ;)
******

Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610



Цитата
но пишу на Си, регистры все заняты компилятором !!!


Напишите именно эту процедуру на ассемблере.


Кстати, а зачем это делать в динамике? Это же шрифт, как я понимаю? Почему бы его не развернуть заранее?


--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 19th July 2025 - 03:53
Рейтинг@Mail.ru


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