Как оптимизировать эту простую функцию, которая переводит входные биты в слова? - PullRequest
2 голосов
/ 09 июня 2010

Я написал функцию, которая считывает входной буфер байтов и создает выходной буфер слов, где каждое слово может быть либо 0x0081 для каждого бита ON входного буфера, либо 0x007F для каждого бита OFF.Длина входного буфера указана.У обоих массивов достаточно физического места.У меня также есть около 2 Кбайт свободной оперативной памяти, которую я могу использовать для поиска таблиц или около того.

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

void inline BitsToWords(int8    *pc_BufIn, 
                        int16   *pw_BufOut, 
                        int32   BufInLen)
{
 int32 i,j,z=0;

 for(i=0; i<BufInLen; i++)
 {
  for(j=0; j<8; j++, z++)
  {
   pw_BufOut[z] = 
                    ( ((pc_BufIn[i] >> (7-j))&0x01) == 1? 
                    0x0081: 0x007f );
  }
 }
}

Пожалуйста, не предлагайте какую-либо библиотечную, компиляторную или CPU / аппаратную оптимизацию, потому что это многоПроект платформы.

Ответы [ 12 ]

0 голосов
/ 09 июня 2010

Что сразу приходит на ум:

  • Разверните внутренний цикл (компилятор уже может это сделать, но вы можете оптимизировать его, если сделаете это вручную, см. Ниже)
  • Вместо того, чтобы держать «z», сохраняйте указатель, который увеличивается (компилятор мог бы сделать это уже)
  • Вместо того, чтобы выполнять сравнение, для каждого развернутого элемента сдвиньте смещение, которое вы извлекли, чтобы оно находилось воместо.Добавьте это к 0x7f и поместите это в значение.Это даст вам 0x7F или 0x81 для каждого.

Лучше всего посмотреть, какой ассемблер сгенерирован для ваших целевых платформ, и посмотреть, что делает компилятор.

РЕДАКТИРОВАТЬ: я бы не использовал таблицу поиска.Стоимость дополнительных пропусков кэша, вероятно, будет больше, чем стоимость простого вычисления.

EDIT2: Позвольте мне перейти на другой компьютер и запустить компилятор, и я посмотрю, что я могу сделать.

0 голосов
/ 09 июня 2010

Я собирался предложить повышение :: for_each, так как это разрушило бы цикл, но конец не известен. Лучшее, что я думаю, вы получите, это распутать внутренний цикл. Я бы искал способы сделать это. Там может быть опция boost :: for_each поверх mpl :: range.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...