Chani
Chani

Reputation: 5165

Compile time processing of parameters

I have to eat some data from two data channels into two queues. Data eaten from each particular channel has to be written to its respective queue.

Thus I have a function :

void eatData(channel c, channel id)
{
   while (true)
   {
      if (channelid == 1)
      {
         write to queue 1;
      }
      else 
      {
         write to queue 2;
      }
   }
}

Notice the while loop I am polling for data and the application is very, very time sensitive. Is there a way of getting rid of those if conditions without writing two different functions like this:

void eatDataFromChannelOneAndWriteToQueueOne()
void eatDataFromChannelTwoAndWriteToQueueTwo()

Can templates be used to solve this?

Upvotes: 0

Views: 106

Answers (2)

Ripple
Ripple

Reputation: 1265

I guess templates would help you, such as:

template<int>
struct QueueSelector
{
    static YourQueue& Queue; 
};

template<int CH>
YourQueue& QueueSelector<CH>::Queue = queue2;

template<>
YourQueue& QueueSelector<1>::Queue = queue1;

template<int CH>
void eatData()
{
    processing with QueueSelector<CH>::Queue
}

Upvotes: 1

Thomas Matthews
Thomas Matthews

Reputation: 57688

Since this code is time sensitive, I suggest you use a std::vector of queues:

static std::vector<Queue_Type> data_container(MAXIMUM_CHANNELS);

void Collect_Data(const& Datum d,
                  unsigned int channel_number)
{
  data_container[channel_number].insert_value(d);
}

The code above is using the std::vector constructor that specifies the initial number of elements for the vector. Having a vector dynamically resize is a waste of time. Also, the fixed initial size allows the vector to be treated as an array without the need to resize.

For circular queues, I recommend using capacities that are powers of 2 so that you can use binary AND operation instead of modulo. We made this change and our performance increased dramatically, especially since our processor does not have any division or modulo instructions.

Edit 1:
If your issue is reading from multiple ports, then you stick the assignment into a forever loop:

void Read_Multiple_Ports(void)
{
  unsigned int channel_number = 0;
  while (true)
  {
    const Datum d = Read_Channel(channel_number);
    data_container[channel_number].insert_value(d);
    ++channel_number;

    // Use if statement rather than modulo
    // because modulo (division) may be more time
    // expensive than a jump.
    // If the number of channels is a power of 2,
    //    this could be replaced by an arithmetic AND
    //    to mask the value.
    if (channel_number >= MAXIMUM_CHANNELS)
    {
      channel_number = 0;
    }
  }
}

Upvotes: 2

Related Questions