Автор Тема: Blur на разных ЯП.  (Прочитано 47843 раз)

valexey_u

  • Hero Member
  • *****
  • Сообщений: 3013
    • Просмотр профиля
Re: Blur на разных ЯП.
« Ответ #120 : Май 01, 2014, 06:22:09 pm »
Реализовал вариант на Джулии (http://julialang.org):

module Blur
export blur

const width = 640
const height = 480
const blur_range = 13

const RED   = 0
const GREEN = 1
const BLUE  = 2

function index(x::Int64,y::Int64, color::Int64)
    return width*y*3 + x*3 + color + 1
end

function blur!(inp::Array{Uint8,1}, out::Array{Uint8,1})
    for y = 1:height-2
        for x = 1:width-2
            @inbounds out[index(x,y,RED)] =  (
                inp[index(x,y-1,RED)] +
                inp[index(x,y+1,RED)] +
                inp[index(x-1,y,RED)] +
                inp[index(x+1,y,RED)]) >> 2
            @inbounds out[index(x,y,GREEN)] =  (
                inp[index(x,y-1,GREEN)] +
                inp[index(x,y+1,GREEN)] +
                inp[index(x-1,y,GREEN)] +
                inp[index(x+1,y,GREEN)]) >> 2
            @inbounds out[index(x,y,BLUE)] =  (
                inp[index(x,y-1,BLUE)] +
                inp[index(x,y+1,BLUE)] +
                inp[index(x-1,y,BLUE)] +
                inp[index(x+1,y,BLUE)]) >> 2
        end
    end
end

function blur()
    const frames = 1000

    input  = Array(Uint8, height*width*3)
    output = Array(Uint8, height*width*3)

    const blur_range = 13
    for f = 1:frames
        for i = 1:blur_range
            blur!(input, output)
            blur!(output, input)
        end
    end
end

end

Обратите внимание на макрос @inbounds - этот макрос отключает проверку выхода за краницы массива в данном конкретном statement'e. То есть в отличие от того же ББ, в котором можно отключить проверку границ только для всего модуля целиком, тут можно отключить только в одном, проверенном, выражении.

Результаты:
== With array bound checks ===
Julia:
    time: 77 sec
    fps : 13
== Without array bound checks ===
Julia:
    time: 32 sec
    fps : 31

А вообще, рекорд скорости у С++ и Ada приложений, если использовать свежий gcc - там используются simd-инструкции, и отрабатывает оно примерно за 17 секунд (а код С++ собранный MSVS 2012 отрабатывает за 60 секунд).

В Julia в принципе тоже есть экспериментальная поддержка SIMD, можно попробовать поиграться.

В общем и в целом скоростью и удобством Julia я удовлетворен.

PS. Напомню, что рекорд BB - это 77 секунд, с использованием SYSTEM и отключением проверки границ массивов.
Y = λf.(λx.f (x x)) (λx.f (x x))