1

Is there a way to deal with bits in c++(c is ok too!) in a way to emulate an encoder(or decoder) logic gate?

For example: encoding a byte(8 bits) into only 3 bits, or a word (16 bits) into 4 bits only and vise versa. exactly in the way encoder and decoder logic gate do it.

The goal of this is data compression (I know that there are better ways, but this is a single phase of the process and it must be done in this way for the project purposes)

Encoder Logic gate:

Encoder Logic gate

Decoder Logic gate:

Decoder Logic gate

Note: it can be done with bitwise operators but I need a really really fast and efficient way so that I can do it billions of times peer second!

Muhammad Nihad
  • 95
  • 2
  • 12
  • Take a look at `std::vector`, it is a specialized representation of a bitset. – Botje Sep 27 '19 at 10:22
  • Well, kind of both yes and no. C++ has bit-wise operations and bit-fields so "yes, that logic can be implemented` but you can't save just 3 bits. You'll always have to use at least 8 bits in memory so you won't really gain anything. So "no, not really". – Support Ukraine Sep 27 '19 at 10:25
  • @Botje what about the efficiency side? I added a little note to the end of the post, read it, please – Muhammad Nihad Sep 27 '19 at 10:55
  • @4386427 Yup I know, what I meant by that was using only 3 bits of a byte to store the encoding result,and having the remaining 5 bits to store data from other encoded bytes. – Muhammad Nihad Sep 27 '19 at 11:09
  • @MuhammadNihad you are aware that the `Dn` is a one-hot type and that coding/decoding fails if more than one `Dn` is set. ? – Support Ukraine Sep 27 '19 at 11:16
  • @4386427 Sorry, but what do you mean by Dn? – Muhammad Nihad Sep 27 '19 at 11:46
  • 1
    Please don't add requirements after the fact. @YvesDaoust 's implementation is 10 instructions. Assuming the case of 1 instruction per cycle, this will yield hundreds of millions of invocations per second on a single core. If you really need to hit that target, you will either need to use multiple cores and eat the coordination/memory overhead, or switch to SIMD and eat extra complexity. – Botje Sep 27 '19 at 11:51
  • 2
    "do it billions of times peer second" -- based on the knowledge displayed in the question, that's a rather unrealistic goal. Especially if you want to do something practical, i.e. feeding some meaningful data in, and doing something with the results rather than just throwing them away. – Dan Mašek Sep 27 '19 at 11:57
  • @MuhammadNihad By `Dn` I mean the input bit `D0`, `D1`, `D2` ... – Support Ukraine Sep 27 '19 at 11:59
  • @DanMašek: simulating a complex ASIC or FPGA would be a legitimate application requiring high performance. –  Sep 27 '19 at 14:01

2 Answers2

2

If you pack the bits in bytes,

Encoder:

Q= 4 * ((D & 0xF0) != 0) + 2 * ((D & 0x66) != 0) + ((D & 0xAA) != 0);

Decoder:

D = 1 << Q;

If you want a faster encoder,

byte QTable[]= {
  0, 0, 3, 3, 2, 2, 3, 3, 1, 1, 3, 3, 3, 3, 3, 3, 
  4, 4, 7, 7, 6, 6, 7, 7, 5, 5, 7, 7, 7, 7, 7, 7, 
  7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
  7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
  6, 6, 7, 7, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
  6, 6, 7, 7, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
  7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
  7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
  5, 5, 7, 7, 7, 7, 7, 7, 5, 5, 7, 7, 7, 7, 7, 7, 
  5, 5, 7, 7, 7, 7, 7, 7, 5, 5, 7, 7, 7, 7, 7, 7, 
  7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
  7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
  7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
  7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
  7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
  7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
};

Q= QTable[D];
  • Thanks for your help :) I already know about the bitwise operators, but is this way efficient enough to achieve the note I added to the end of the post? – Muhammad Nihad Sep 27 '19 at 11:00
  • @MuhammadNihad: mh, feel free to improve the decoder. –  Sep 27 '19 at 12:39
2

it can be done with bitwise operators but I need a really really fast and efficient

Since your input is pretty limited, i.e. 8 bits, I would go for a look-up table. The table can be based on a vector (or a simple array).

const uint8_t illegal_value = 0xff;
std::vector<uint8_t> encoder_table(256, illegal_value);
encoder_table[1] = 0;
encoder_table[2] = 1;
encoder_table[4] = 2;
encoder_table[8] = 3;
encoder_table[16] = 4;
encoder_table[32] = 5;
encoder_table[64] = 6;
encoder_table[128] = 7;

// Encode:
uint8_t D = a_one_hot_value;
uint8_t Q = encoder_table[D];

The relevant parts of the table is likely to stay in the level 1 cache all the time so performance should be quite good.

For decoding I will expect a simple bit shift to be the most efficient solution

// Decode:
uint8_t D = 1 << Q;

but a table can be tried for comparison. That table will only require 8 entries. Again something small that can be in level 1 cache.

Toby Speight
  • 27,591
  • 48
  • 66
  • 103
Support Ukraine
  • 42,271
  • 4
  • 38
  • 63