Кэширование Floating Point

Для неординарных вопросов. Если вы опытный программист, попавший в трудную ситуацию, — вам сюда.

Модератор: gaidar

Правила форума
Этот раздел не предназначен для того, чтобы вы адресовали свою проблему профессионалам.
Этот раздел предназначен для профессионалов, которые столкнулись с проблемой и не могут решить ее самостоятельно.
Если вы считаете себя профессионалом, а свою проблему сложной — вам сюда.
Если модератор посчитает, что вы ошиблись, то на первый раз он перенесет ваше сообщение в основной раздел без последствий для автора. Во второй раз тема будет закрыта, а автору будет выписано нарушение. В третий раз автор будет забанен.
AWPStar
Начинающий
Начинающий
 
Сообщения: 16
Зарегистрирован: 29.07.2010 (Чт) 2:32

Кэширование Floating Point

Сообщение AWPStar » 31.10.2014 (Пт) 2:42

Понадобилось перевести все фильтры в вычисление в single для большей точности и возможности выхода за диапазон[0-255]...

...Но как кэшировать вычисления с Floating Point(Single, Double)?

с Байтом все просто - таблица [0 - 255], а тут как?

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Кэширование Floating Point

Сообщение Хакер » 31.10.2014 (Пт) 9:30

Если не брать во внимание глупость изначальной задумки, то решение влоб: завести на диске файл размером 16 Гб и использовать его как lookup-таблицу по аналогии с байтом.

Если такой размер файла не устраивает, его можно сократить, уменьшив область определения: например отказ от отрицательных чисел даёт сокращение уже до 8 Гб. Дальше можно сократить, ограничив диапазон показателей степени.

Но я конечно это говорю с иронией.

Потому что правильный подход: начать с рассказа о том, что там за математика и какие свойства у вычисляемых выражений (периодичность, линейность). Рассказать о требуемой точности, диапазоне значений, обосновать применений FP-аргументов для lookup-а. А там уже появляются варианты с B-деревьями и интерполяцией.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

AWPStar
Начинающий
Начинающий
 
Сообщения: 16
Зарегистрирован: 29.07.2010 (Чт) 2:32

Re: Кэширование Floating Point

Сообщение AWPStar » 31.10.2014 (Пт) 11:11

Если не брать во внимание глупость изначальной задумки
обосновать применений FP-аргументов
-К примеру, блюр, который в тенях пожерает все детали, а после вытаскивания теней картинка становиться как после постеризации.
-После обработки возможен dithering.
-32 битный Single обрабатывается быстрее 16-битного int(по тестам где-то на 17%)

Точность высокая не требует, даже, в принципе 2 знака после запятой хватит.
Выход за границы диапазонов должен быть также возможен как в нижнюю часть, так и в верхнюю

Вот пример фильтра
Код: Выделить всё
    ' FILM CONTRAST
    Public Sub flt_s_film (DT As Single PTR, ByVal LN As Long, ByVal V1 As Single, ByVal V2 As Single, ByVal Lg As Long, ByVal Pc As Long) EXPORT
        If V1 = 0 Then
            If v2 = 0 Then
                If Lg = 0 Then
                    Exit Sub
                End If
            End If
        End If

        Dim X As Long, k As Long
        Dim kk As Single, i As Long
        Dim Y As Single, R As Single, G As Single, B As Single
        Dim ln3 As Long = ln * 3
       
        Dim C1 As Single
        Dim C2 As Single

        If V1 < - 40 Then V1 = - 40
        If V1 > 40 Then V1 = 40
       
        If V2 < - 50 Then V2 = - 50
        If V2 > 100 Then V2 = 100
       
        If V2 < 0 Then
            kk = (100 + V2) / 100
        Else
            kk = 1 + V2 / 100
        End If
       
       
        C1 = V1 * kk
        C2 = - 128 * kk + 128
             
             
            ' INIT FILTER TABLE
'            For x = 0 To 255
'                i = (x + Sin(x / 40.5845104) * V1 - 128) * kk + 128
'                If Lg = 1 Then i = Sqr(i * 64) * 2
'                If i < 0 Then i = 0
'                If i > 255 Then i = 255
'                filmc(x) = i
'            Next
           
           
            'i = (x + Sin(x / 40.5845104) * V1 - 128) * kk + 128
            '     x * kk + Sin(x / 40.5845104) * V1 * kk - 128 * kk + 128
            '                                    V1 * kk  -128 * kk + 128
            '     x * kk + sin(x / 40.5845104) *    C1   +   C2
            '     C1 = V1 * kk      C2 = -128 * kk + 128
           
            'i = 16*sqr(((x + Sin(x / 40.5845104) * V1 - 128) * kk + 128))
            '    16*sqr(x * kk + sin(x / 40.5845104) *    C1   +   C2 )
        If Pc = 0 Then
            If Lg = 0 Then
                stt9: If k = ln3 Then Exit Sub
                    DT[k] = DT[k] * kk + Sin(DT[k] / 40.5845104) * C1 + C2
                    k = k + 1
                Goto stt9:
            Else
                stt10: If k = ln3 Then Exit Sub
                    DT[k] = 16 * Sqr(DT[k] * kk + Sin(DT[k] / 40.5845104) * C1 + C2 )
                    k = k + 1
                Goto stt10:
            End If
        Else
            Dim kR As Long = 2
            Dim kG As Long = 1

            If Lg = 0 Then
                sttp9: If k = ln3 Then Exit Sub
                    Y = (DT[k] + DT[kG] + DT[kR]) / 3
                    B = DT[k] - Y
                    G = DT[kG] - Y
                    R = DT[kR] - Y
                   
                    Y = Y * kk + Sin(Y / 40.5845104) * C1 + C2
                   
                    DT[k] = Y + B
                    DT[kG] = Y + G
                    DT[kR] = Y + R
                    k += 3
                    kG += 3
                    kR += 3
                Goto sttp9:
            Else
                sttp10: If k = ln3 Then Exit Sub
                    Y = (DT[k] + DT[kG] + DT[kR]) / 3
                    B = DT[k] - Y
                    G = DT[kG] - Y
                    R = DT[kR] - Y
                   
                    Y = 16 * Sqr(Y * kk + Sin(Y / 40.5845104) * C1 + C2 )
                   
                    DT[k] = Y + B
                    DT[kG] = Y + G
                    DT[kR] = Y + R
                   
                    k += 3
                    kG += 3
                    kR += 3
                Goto sttp10:
            End If
'            Dim kR As Long = 2
'            Dim kG As Long = 1
'           
'            stt10: If k > ln3 Then Exit Sub
'                Y = filmGray(CLng(DT[k]) + DT[kG] + DT[kR])
'                B = Y - DT[k]
'                G = Y - DT[kG]
'                R = Y - DT[kR]
'                Y = filmc(Y)
'                DT[k] = clim(Y - B)
'                DT[kG] = clim(Y - G)
'                DT[kR] = clim(Y - R)
'                k += 3
'                kG += 3
'                kR += 3
'            Goto stt10:
           
        End If
    End Sub

Debugger
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1667
Зарегистрирован: 17.06.2006 (Сб) 15:11

Re: Кэширование Floating Point

Сообщение Debugger » 31.10.2014 (Пт) 13:08

Переводи флоат в байт и делай лукап по нему:
byte = (Single - min) / max * 255
min, max - минимальное и максимальное значение Single на выходе фильтра.
Если значение получается меньше 0, то округляем до 0, если больше 255 - округляем до 255.

Если серьезно - по-человечески переписав код, можно получить выигрыш более, чем на 17%.
Нужна скорость, близкая к реалтайму - напиши функцию на Си, подключи как библиотеку.
Если нужно ещё больше - напиши на ассемблере. Хотя, от Си отличаться будет не принципиально.
А по-хорошему, если важна скорость отклика - почитай про DirectX, и сделай шейдер.

Qwertiy
Доктор VB наук
Доктор VB наук
 
Сообщения: 2753
Зарегистрирован: 26.06.2011 (Вс) 21:26

Сообщение Qwertiy » 31.10.2014 (Пт) 13:21

AWPStar писал(а):-32 битный Single обрабатывается быстрее 16-битного int(по тестам где-то на 17%)

Писали, что 32-битный Long самый быстрый из целочисленных.

Mikle
Изобретатель велосипедов
Изобретатель велосипедов
Аватара пользователя
 
Сообщения: 4148
Зарегистрирован: 25.03.2003 (Вт) 14:02
Откуда: Туапсе

Re: Кэширование Floating Point

Сообщение Mikle » 31.10.2014 (Пт) 19:20

Я так понял, нужно загнать в таблицу значения:
Код: Выделить всё
Dim Ar() As Single, TabSz As Long

Sub FilmcInit(ByVal Lg As Long, ByVal Pc As Long)
  Dim x As Long, i As Single

  ReDim Ar(255)
  For x = 0 To 255
    i = (x + Sin(x / 40.5845104) * V1 - 128) * kk + 128
    If Lg = 1 Then
      i = Sqr(i * 64) * 2
    End If
    If Pc = 0 Then
      If i < 0 Then i = 0
      If i > 255 Then i = 255
    End If
    Ar(x) = i
  Next i
End Sub

А потом использовать такую функцию:

Код: Выделить всё
Function Filmc(ByVal s As Single) As Single
  Dim i As Long

  i = Int(s): s = s - i
  Filmc = Ar(i) * (1 - s) + Ar(i + 1) * s
End Function

AWPStar
Начинающий
Начинающий
 
Сообщения: 16
Зарегистрирован: 29.07.2010 (Чт) 2:32

Re: Кэширование Floating Point

Сообщение AWPStar » 31.10.2014 (Пт) 20:02

Попробую интерполяцией
Код: Выделить всё
Ar(i) * (1 - s) + Ar(i + 1) * s
все таки быстрее полных вычислений, но не уверен, что линейность будет незаметна на глаз.


Вернуться в Раздел для Профессионалов

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 14

    TopList