Shaos wrote:Надо проверить, а не быстрее ли будет просто с int-ами работать (-1, 0, +1), а не использовать <nil> как третье состояние - nil это же скорее исключительная ситуация, чем нормальная работа?
Здравия!
Добавил полный троичный сумматор и в качестве трита как int данное.
Производительность sum_t
Code: Select all
goos: linux
goarch: amd64
BenchmarkSum_t-8 236201059 4.88 ns/op 0 B/op 0 allocs/op
PASS
ok
Исследовал разные реализации тритов и трайтов в эмуляторе "Setun-1958" с целью производительности операций в ARM-архитектуре и максимально близко к инструкциям микроконтроллера:
(Вариант 1) BITS
'00' '10' '01' '11'
Трит:
typedef uint32_t trit;
Слово из тритов:
typedef struct trs {
int w;
int l;
uint64_t trit; // для 18 трит * 2 = 36 бит для регистра "Setun"
} trs_t;
(Вариант 2) INT
/* Тип данных троичное целое число */
typedef struct trin {
int n;
int trit[SIZE_WORD_EMUL];
} trit_t;
Посмотрел генерацию кода в ассемблер из С.
Медленная реализация эмуляции работы со словами регистров "Setun-1958":
1,5,9,18 тритов.
Идею использовать "false,nil,true" подглядел здесь на форуме.
Code: Select all
// Таб.1 Алфавит троичной симметричной системы счисления
// +--------------------------+-------+-------+-------+
// | Числа | -1 | 0 | 1 |
// +--------------------------+-------+-------+-------+
// | Символы (вар.1) | - | 0 | + |
// +--------------------------+-------+-------+-------+
// | Символы (вар.2) | v | 0 | ^ |
// +--------------------------+-------+-------+-------+
// | Символы (вар.3) | N | O | P |
// +--------------------------+-------+-------+-------+
// | Символы (вар.4) | 0 | i | 1 |
// +--------------------------+-------+-------+-------+
// | Логика | false | nil | true |
// +--------------------------+-------+-------+-------+
Многие микроконтроллеры имеют битовые операции установки, очистки бита. Условный переход посотоянию бита.
Быстрый код операций на обычном двоичном процессоре, на мой взгляд, можно обеспечить так
TRYTE[6]
byte1 [5][4][3][2][1][0]
byte0 [5][4][3][2][1][0]
TRIT0 = {byte1[0],byte0[0]}
byte1[0] = {false,true}
byte1[0] = {false,true}
if ( byte0[0] == 0 ) {
TRIT= NIL
}
else {
if (byte1[0] == 0 )
{
TRIT = -1
}
else
{
TRIT = 1
}
}
- Упрощается троичный сдвиг, сдвигая разряды byte1, byte0 командами двоичного процессора.
- Упрощается умножение byte0[0] маскирует разряды
Например, для контроллера AVR
CBR Rd, K Очистка разрядов регистра Rd ← Rd and (0FFH – K) Z, N, V
SBR Rd, K Установка разрядов регистра Rd ← Rd or K Z, N, V
LSL Rd Логический сдвиг влево Rd(i+1) ← Rd(i), Rd(0) ← 0, C ← Rd(7) Z, C, N, V
LSR Rd Логический сдвиг вправо Rd(i) ← Rd(i+1), Rd(7) ← 0, C ← Rd(0) Z, C, N, V
ROL Rd Сдвиг влево через перенос Rd(i+1) ← Rd(i), Rd(0) ← C, C ← Rd(7) Z, C, N, V
ROR Rd Сдвиг вправо через перенос Rd(i) ← Rd(i+1), Rd(7) ← C, C ← Rd(0) Z, C, N, V
SBRC Rd, K Пропустить следующую команду если бит в регистре очищен Если Rd[K] = 0 —
SBRS Rd, K Пропустить следующую команду если бит в регистре установлен Если Rd[K] = 1 —
Например, в ARM Cortex STM32
реализован способ управлять битами памяти, портов с использованием
memory bitband
https://blablacode.ru/mikrokontrollery/455
Как работает Bit Banding?
Bit Banding – термин, который использует ARM для обозначения механизма доступного в Cortex M3 and M4 ядрах. Если говорить просто, то в устройстве берется участок памяти и каждый бит этого участка связывается со словом в другом участке памяти.
«Магия» Bit Banding в том, что при записи слов данных во второй участок, изменяются биты в первом. Операция установки, снятия бита занимает одну машинную инструкцию, что делает невозможным потерю данных. Т.е. такой подход обеспечивает атомарный доступ к памяти.
"Ученье свет, а неученье — тьма. Дело мастера боится, и коль крестьянин не умеет сохою владеть — хлеб не родится." (С)