Преобразуйте буфер БАЙТА (0-255) для плавания буфера (0.0-1.0)

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

Еще лучшим примером может быть OpenGL. OpenGl - это API, который по-разному реализован AMD и NVidia. И вы не можете использовать реализацию NVidia на карте AMD, потому что аппаратное обеспечение отличается. Из-за этого вы не можете статически связать OpenGL с вашей программой. Динамическое связывание используется здесь, чтобы позволить API быть оптимизированным для всех платформ.

7
задан mskfisher 10 May 2012 в 18:51
поделиться

6 ответов

Whether you choose to use a lookup table or not, your code is doing a lot of work each loop iteration that it really does not need to - likely enough to overshadow the cost of the convert and multiply.

Declare your pointers restrict, and pointers you only read from const. Multiply by 1/255th instead of dividing by 255. Don't calculate the pointers in each iteration of the inner loop, just calculate initial values and increment them. Unroll the inner loop a few times. Use vector SIMD operations if your target supports it. Don't increment and compare with maximum, decrement and compare with zero instead.

Something like

float* restrict floatpixel = floatbuffer;
BYTE const* restrict bytepixel = bytebuffer;
for( int size = width*height; size > 0; --size )
{
    floatpixel[0] = bytepixel[0]*(1.f/255.f);
    floatpixel[1] = bytepixel[1]*(1.f/255.f);
    floatpixel[2] = bytepixel[2]*(1.f/255.f);
    floatpixel[3] = 1.0f; // A
    floatpixel += 4;
    bytepixel += 4;
}

would be a start.

9
ответ дан 6 December 2019 в 07:52
поделиться

Не вычисляйте каждый раз 1/255. Не знаю, хватит ли у компилятора умен, чтобы это удалить. Рассчитайте его один раз и применяйте каждый раз повторно. Еще лучше, определите его как константу.

0
ответ дан 6 December 2019 в 07:52
поделиться

Да, таблица поиска определенно быстрее, чем выполнение большого количества делений в цикле. Просто создайте таблицу из 256 предварительно вычисленных значений с плавающей запятой и используйте значение байта для индексации этой таблицы.

Вы также можете немного оптимизировать цикл, удалив вычисление индекса и просто сделав что-то вроде

float *floatpixel = floatbuffer;
BYTE *bytepixel = bytebuffer;

for (...) {
  *floatpixel++ = float_table[*bytepixel++];
  *floatpixel++ = float_table[*bytepixel++];
  *floatpixel++ = float_table[*bytepixel++];
  *floatpixel++ = 1.0f;
}
1
ответ дан 6 December 2019 в 07:52
поделиться

Используйте для этого статическую таблицу поиска. Когда я работал в компании, занимающейся компьютерной графикой, у нас появилась жестко закодированная таблица поиска для этого, которую мы связали с проектом.

2
ответ дан 6 December 2019 в 07:52
поделиться

Вам нужно выяснить, в чем заключается узкое место:

  • если вы повторяете свои таблицы данных в «неправильном» направлении, вы постоянно получаете промах в кэше. Никакой поиск никогда не поможет обойти это.
  • если ваш процессор масштабируется медленнее, чем поиск, вы можете повысить производительность, выполнив поиск, при условии, что таблица поиска соответствует его кэшу.

Другой совет:

struct Scale {
    BYTE operator()( const float f ) const { return f * 1./255; }
};
std::transform( float_table, float_table + itssize, floatpixel, Scale() );
2
ответ дан 6 December 2019 в 07:52
поделиться

Поисковая таблица - это самый быстрый способ преобразования :) Вот, пожалуйста:

Код Python для создания файла byte_to_float.h, который должен включать:

#!/usr/bin/env python

def main():
    print "static const float byte_to_float[] = {"

    for ii in range(0, 255):
        print "%sf," % (ii/255.0)

    print "1.0f };"    
    return 0

if __name__ == "__main__":
    main()

И код C ++ для преобразования:

floatpixel[0] = byte_to_float[ bytepixel[0] ];

Simple isn не так ли?

1
ответ дан 6 December 2019 в 07:52
поделиться
Другие вопросы по тегам:

Похожие вопросы: