Oberon space

General Category => Общий раздел => Тема начата: valexey_u от Апрель 24, 2013, 04:34:26 pm

Название: Blur на разных ЯП.
Отправлено: valexey_u от Апрель 24, 2013, 04:34:26 pm
Коль пошла такая пьянка, предлагаю погонять один и тот же алгоритм блюра на разных ЯП. Ну и попробовать, возмжно, оптимизировать производительность не изменяя самого алгоритма.

Начало темы, тут: http://oberspace.dyndns.org/index.php/topic,480.msg15786.html#msg15786

Рассматриваем только алгоритм Сергея. Краткое описание алгоритма (наивная реализация для одного цветового канала флоатов на C#):
const int N = 13;

for (int n = 0; n < N; n++)
{

  for (int y = 1; y < 479; y++)
  {
    for (int x = 1; x < 639; x++)
    {
      b[y, x] = 0.25 * (a[y - 1, x] + a[y + 1, x] + a[y, x - 1] + a[y, x + 1]);
    }
  }

  for (int y = 1; y < 479; y++)
  {
    for (int x = 1; x < 639; x++)
    {
      a[y, x] = 0.25 * (b[y - 1, x] + b[y + 1, x] + b[y, x - 1] + b[y, x + 1]);
    }
  }
}

Продублирую и дополню и вычищу то, что содержалось в том сообщении (из дополнительного - появилась реализация на КП/ББ):

Итак, вначале результаты. Напомню, что радиус размытия (N) = 13. Обрабатываются все три канала. Число обрабатываемых кадров = 1000.

C#:
   time: 107 seconds
   fps : 9.35
С++:
   time: 96 seconds
   fps : 10.42
BB/CP (2D массивы аналогично наивной реализации на C#):
   time: 439 seconds
   fps : 2.28
BB/CP (1D массивы, функция вычисления индекса - аналогично C++):
   time: 688 seconds
   fps : 1.45

Исходники:
C#:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication5
{
    class Program
    {
        static unsafe void Main(string[] args)
        {
            const int H = 480;
            const int W = 640;
            byte[] a = new byte[H * W * 3];
            byte[] b = new byte[H * W * 3];

            System.Diagnostics.Stopwatch timer = new System.Diagnostics.Stopwatch();
            const int N = 13;
            timer.Reset();
            timer.Start();
            const int frames = 1000;
            for (int nn = 0; nn<frames; nn++)
            {
                fixed (byte* pa = &a[0])
                {
                    fixed (byte* pb = &b[0])
                    {
                        for (int n = 0; n < N; n++)
                        {
                            for (int y = 1; y < H - 1; y++)
                            {
                                for (int x = 1; x < W - 1; x++)
                                {
                                    for (int color_shift = 0; color_shift < 3; color_shift++)
                                    {
                                        *(pb + (H * y + x) * 3 + color_shift) = (byte)(0.25 * (*(pa + (H * (y - 1) + x) * 3 + color_shift)
                                        + *(pa + (H * (y + 1) + x) * 3 + color_shift)
                                        + *(pa + (H * y + x - 1) * 3 + color_shift)
                                        + *(pa + (H * y + x + 1) * 3 + color_shift)));
                                    }
                                }
                            }
                            for (int y = 1; y < H - 1; y++)
                            {
                                for (int x = 1; x < W - 1; x++)
                                {
                                    for (int color_shift = 0; color_shift < 3; color_shift++)
                                    {
                                        *(pa + (H * y + x) * 3 + color_shift) = (byte)(0.25 * (*(pb + (H * (y - 1) + x) * 3 + color_shift)
                                            + *(pb + (H * (y + 1) + x) * 3 + color_shift)
                                            + *(pb + (H * y + x - 1) * 3 + color_shift)
                                            + *(pb + (H * y + x + 1) * 3 + color_shift)));
                                    }
                                }
                            }
                        }
                    }
                }
            }

            timer.Stop();
            double dt = timer.Elapsed.TotalSeconds;
            System.Console.WriteLine("N = {0} (R = {1}), dt={2} seconds, FPS = {3}",
                N, 2 * N, dt, (frames / dt));

            System.Console.ReadLine();
        }
    }
}

C++:
#include <iostream>
#include <ctime>

const int width = 640;
const int height = 480;
const size_t blurRange = 13;

enum Color {
    RED = 0,
    GREEN,
    BLUE
};

int index(int x, int y, Color color) {
    return width*y*3+x*3+color;
}

int main()
{
    volatile unsigned char* volatile in  = new unsigned char[width*height*3];
    volatile unsigned char* volatile out = new unsigned char[width*height*3];

    time_t begin;
    time(&begin);

    const int frames = 1000;

    for (int nn=0; nn<frames; nn++) {
        for (int i=0; i<blurRange; i++) {

            for (int y=1; y<height-1; y++)
                for (int x=1; x<width-1; x++) {
                    out[index(x,y,RED)]= 0.25*(
                        (float)in[index(x,y-1,RED)]+
                               in[index(x,y+1,RED)]+
                               in[index(x-1,y,RED)]+
                               in[index(x+1,y,RED)]);
                    out[index(x,y,GREEN)]= 0.25*(
                        (float)in[index(x,y-1,GREEN)]+
                               in[index(x,y+1,GREEN)]+
                               in[index(x-1,y,GREEN)]+
                               in[index(x+1,y,GREEN)]);
                    out[index(x,y,BLUE)]= 0.25*(
                        (float)in[index(x,y-1,BLUE)]+
                               in[index(x,y+1,BLUE)]+
                               in[index(x-1,y,BLUE)]+
                               in[index(x+1,y,BLUE)]);
                }

            for (int y=1; y<height-1; y++)
                for (int x=1; x<width-1; x++) {
                    in[index(x,y,RED)]=0.25*(
                        (float)out[index(x,y-1,RED)]+
                               out[index(x,y+1,RED)]+
                               out[index(x-1,y,RED)]+
                               out[index(x+1,y,RED)]);
                    in[index(x,y,GREEN)]=0.25*(
                        (float)out[index(x,y-1,GREEN)]+
                               out[index(x,y+1,GREEN)]+
                               out[index(x-1,y,GREEN)]+
                               out[index(x+1,y,GREEN)]);
                    in[index(x,y,BLUE)]=0.25*(
                        (float)out[index(x,y-1,BLUE)]+
                               out[index(x,y+1,BLUE)]+
                               out[index(x-1,y,BLUE)]+
                               out[index(x+1,y,BLUE)]);
                }
        }
    }

    time_t end;
    time(&end);
    auto seconds = difftime(end, begin);
    std::cout << float(frames)/seconds << " " << seconds << std::endl;
}

Тестовый модуль на КП. Две функции:
Blur2DArray - реализация на 2D массивах
Blur1DArray - реализация на одномерных массивах.
MODULE Blur;
IMPORT Kernel, Out:=StdLog;

CONST
W = 640;
H = 480;
N = 13;
Frames = 1000;

TYPE
Plane = ARRAY W*3, H OF BYTE;
Plane1 = ARRAY W*H*3 OF BYTE;

PROCEDURE Blur2DArray*;
VAR
time : LONGINT;
f, n : INTEGER;
x, y : INTEGER;
color : INTEGER;
a, b : POINTER TO Plane;
BEGIN
NEW(a);
NEW(b);
time := Kernel.Time();

FOR f:=1 TO Frames DO
FOR n:=1 TO N DO

FOR y:=1 TO H-2 DO
FOR x:=1 TO W-2 DO
FOR color:=0 TO 2 DO
b[x*3+color,y] := SHORT(SHORT(SHORT(ENTIER(0.25*(a[x*3+color,y+1]+a[x*3+color,y-1]+a[(x-1)*3,y]+a[(x+1)*3,y])))));
END
END
END;

FOR y:=1 TO H-2 DO
FOR x:=1 TO W-2 DO
FOR color:=0 TO 2 DO
a[x*3+color,y] := SHORT(SHORT(SHORT(ENTIER(0.25*(b[x*3+color,y+1]+b[x*3+color,y-1]+b[(x-1)*3,y]+b[(x+1)*3,y])))));
END
END
END


END
END;

Out.Real((Kernel.Time() - time)/1000)
END Blur2DArray;

PROCEDURE Index(x,y,color : INTEGER) : INTEGER;
BEGIN
RETURN ((x+y*W)*3+color)
END Index;

PROCEDURE Blur1DArray*;
VAR
time : LONGINT;
f, n : INTEGER;
x, y : INTEGER;
color : INTEGER;
a, b : POINTER TO Plane1;
BEGIN
NEW(a);
NEW(b);
time := Kernel.Time();

FOR f:=1 TO Frames DO
FOR n:=1 TO N DO

FOR y:=1 TO H-2 DO
FOR x:=1 TO W-2 DO
FOR color:=0 TO 2 DO
b[Index(x,y,color)] := SHORT(SHORT(SHORT(ENTIER(0.25*(a[Index(x,y+1,color)]+a[Index(x,y-1,color)]+a[Index(x-1,y,color)]+a[Index(x+1,y,color)])))));
END
END
END;

FOR y:=1 TO H-2 DO
FOR x:=1 TO W-2 DO
FOR color:=0 TO 2 DO
a[Index(x,y,color)] := SHORT(SHORT(SHORT(ENTIER(0.25*(b[Index(x,y+1,color)]+b[Index(x,y-1,color)]+b[Index(x-1,y,color)]+b[Index(x+1,y,color)])))));
END
END
END;

END
END;

Out.Real((Kernel.Time() - time)/1000)
END Blur1DArray;
BEGIN
END Blur.
Название: Re: Blur на разных ЯП.
Отправлено: Geniepro от Апрель 24, 2013, 04:47:02 pm
Чем умножать целочисленную переменную на 0.25, а потом переводить результат в целочисленный же вид, не проще ли сдвиг на два бита использовать?
(int)(0.25 * x) == (x >> 2)
Название: Re: Blur на разных ЯП.
Отправлено: valexey_u от Апрель 24, 2013, 05:03:18 pm
Чем умножать целочисленную переменную на 0.25, а потом переводить результат в целочисленный же вид, не проще ли сдвиг на два бита использовать?
(int)(0.25 * x) == (x >> 2)
А ты попробуй - исходники все есть :-)
Название: Re: Blur на разных ЯП.
Отправлено: Valery Solovey от Апрель 24, 2013, 05:06:19 pm
А от моих оптимизаций руками эффекта не было?
Название: Re: Blur на разных ЯП.
Отправлено: valexey_u от Апрель 24, 2013, 05:09:20 pm
А от моих оптимизаций руками эффекта не было?
Я еще не пробовал. Народ, попробуйте - я просто не успеваю пробовать все идеи :-)
Название: Re: Blur на разных ЯП.
Отправлено: valexey_u от Апрель 24, 2013, 05:11:14 pm
Чем умножать целочисленную переменную на 0.25, а потом переводить результат в целочисленный же вид, не проще ли сдвиг на два бита использовать?
(int)(0.25 * x) == (x >> 2)
Замена на целочисленное деление на 4 в варианте C++ дало прирост в скорости в 1.5 раза:
C++ (умножение на 0.25):
   time: 92
   fps : 10.87
C++ (деление на 4):
   time: 66
   fps : 15.15
Название: Re: Blur на разных ЯП.
Отправлено: valexey_u от Апрель 24, 2013, 05:26:10 pm
В 2D массивном варианте ББ/КП также при переходе не целочисленку быстродействие поднялось в полтора раза:

BB/CP (2D массивы аналогично наивной реализации на C#, "*0.25"):
   time: 439 seconds
   fps : 2.28
BB/CP (2D массивы аналогично наивной реализации на C#, "/4"):
   time: 303 seconds
   fps : 3.3

Исходник функции (модуль тот же):
PROCEDURE Blur2DArray*;
VAR
time : LONGINT;
f, n : INTEGER;
x, y : INTEGER;
color : INTEGER;
a, b : POINTER TO Plane;
BEGIN
NEW(a);
NEW(b);
time := Kernel.Time();

FOR f:=1 TO Frames DO
FOR n:=1 TO N DO

FOR y:=1 TO H-2 DO
FOR x:=1 TO W-2 DO
FOR color:=0 TO 2 DO
b[x*3+color,y] := SHORT(SHORT((a[x*3+color,y+1]+a[x*3+color,y-1]+a[(x-1)*3,y]+a[(x+1)*3,y]) DIV 4));
END
END
END;

FOR y:=1 TO H-2 DO
FOR x:=1 TO W-2 DO
FOR color:=0 TO 2 DO
a[x*3+color,y] := SHORT(SHORT((b[x*3+color,y+1]+b[x*3+color,y-1]+b[(x-1)*3,y]+b[(x+1)*3,y]) DIV 4));
END
END
END


END
END;

Out.Real((Kernel.Time() - time)/1000)
END Blur2DArray;
Название: Re: Blur на разных ЯП.
Отправлено: ilovb от Апрель 24, 2013, 05:42:20 pm
x*3+color

Зачем так много раз вычислять это? Компилер ведь не оптимизирующий.

Да и вообще можно на одном прогоне эти значения в массив загнать.
Название: Re: Blur на разных ЯП.
Отправлено: valexey_u от Апрель 24, 2013, 05:46:32 pm
x*3+color

Зачем так много раз вычислять это? Компилер ведь не оптимизирующий.

Да и вообще можно на одном прогоне эти значения в массив загнать.

You are welcome!
В смысле, перепиши ББшную процедуру так, как тебе кажется правильным, кинь сюда, также кинь сравнительный замер того что было и что стало на твоей машине, и я тоже прогоню тест на своей.
Название: Re: Blur на разных ЯП.
Отправлено: ilovb от Апрель 24, 2013, 06:51:25 pm
Типа так:
MODULE Blur;
    IMPORT Kernel, Out:=StdLog;
   
    CONST
        W = 640; W1 = 640 - 3;
        H = 480; H1 = 480 - 3;
        N = 13;
        Frames = 1000;
       
    TYPE
        Plane = ARRAY W*3, H OF BYTE;
        Plane1 = ARRAY W*H*3 OF INTEGER;
       
    PROCEDURE Blur2DArray*;
    VAR
        time : LONGINT;
        f, n : INTEGER;
        x, y : INTEGER;
        color : INTEGER;
        a, b : POINTER TO Plane;
        c1, c2, c3, c4: POINTER TO Plane1;
        i: INTEGER;
    BEGIN
        NEW(a);
        NEW(b);
        NEW(c1); NEW(c2); NEW(c3); NEW(c4); i := 0;
        time := Kernel.Time();
       
                FOR y:=1 TO H-2 DO               
                    FOR x:=1 TO W-2 DO
                        FOR color:=0 TO 2 DO
                            c1[i] := x*3+color;
                            c2[i] := (x-1)*3;
                            c3[i] := (x+1)*3;
                            c4[i] := y;
                            INC(i);
                        END
                    END
                END;
       
        FOR f:=1 TO Frames DO
            FOR n:=1 TO N DO
           
                (*FOR y:=1 TO H-2 DO               
                    FOR x:=1 TO W-2 DO
                        FOR color:=0 TO 2 DO
                            b[x*3+color,y] :=
                                (a[x*3+color,y+1] +
                                a[x*3+color,y-1] +
                                a[(x-1)*3,y] +
                                a[(x+1)*3,y]) DIV 4;
                        END
                    END
                END;*)
               
                FOR i := 0 TO W1*H1*3 DO
                    x := c1[i];
                    y := c4[i];
                    b[x, y] := SHORT(SHORT((a[x, y+1] + a[x, y-1] + a[c2[i], y] + a[c3[i], y]) DIV 4));
                END;

                (*FOR y:=1 TO H-2 DO               
                    FOR x:=1 TO W-2 DO
                        FOR color:=0 TO 2 DO
                            a[x*3+color,y] :=
                                (b[x*3+color,y+1] +
                                b[x*3+color,y-1] +
                                b[(x-1)*3,y] +
                                b[(x+1)*3,y]) DIV 4;
                        END
                    END
                END*)
               
                FOR i := 1 TO W1*H1*3 DO
                    x := c1[i];
                    y := c4[i];
                    a[x, y] := SHORT(SHORT((b[x, y+1] + b[x, y-1] + b[c2[i], y] + b[c3[i], y]) DIV 4));
                END;
               
            END
        END;
       
        Out.Real((Kernel.Time() - time)/1000)
    END Blur2DArray;
(*Blur1DArray*)
END Blur.

было ~750 (версия с DIV 4)
стало ~440

Но у меня может быть гон. Ибо антивирус мелкомягкий работает.
Название: Re: Blur на разных ЯП.
Отправлено: ilovb от Апрель 24, 2013, 07:01:56 pm
FOR i := 1 TO W1*H1*3 DOКосяк  :) i := 0 конечно
Название: Re: Blur на разных ЯП.
Отправлено: valexey_u от Апрель 24, 2013, 07:06:54 pm
FOR i := 1 TO W1*H1*3 DOКосяк  :) i := 0 конечно
Ну, это не может сказаться значительно ни на производительности, ни на корректности работы :-)
Название: Re: Blur на разных ЯП.
Отправлено: ilovb от Апрель 24, 2013, 07:08:26 pm
Похоже таки гон. Сейчас еще раз прогнал твой код с DIV и получилось тоже ~440
Название: Re: Blur на разных ЯП.
Отправлено: valexey_u от Апрель 24, 2013, 07:11:17 pm
Похоже таки гон. Сейчас еще раз прогнал твой код с DIV и получилось тоже ~440
Я прогнал твой вариант. Стало медленнее - было 303 (вариант с DIV), стало 378 секунд.

Что в общем то и следовало ожидать - вместо пересылки из регистра в регистр мы получили пересылку из ОЗУ (пусть даже это кэш первого или второго уровня).
Название: Re: Blur на разных ЯП.
Отправлено: ilovb от Апрель 24, 2013, 07:21:55 pm
Значит оптимизации тут роли особой не играют. Скорее всего поможет только отключение проверок.
Название: Re: Blur на разных ЯП.
Отправлено: valexey_u от Апрель 24, 2013, 07:24:05 pm
Значит оптимизации тут роли особой не играют. Скорее всего поможет только отключение проверок.
Возможно имеет смысл вычислять эти оффсеты один раз для всех 4 пикселов. Что-то вроде того, как Валерий предлагал. Надо будет попробовать.
Название: Re: Blur на разных ЯП.
Отправлено: DddIzer от Апрель 24, 2013, 08:28:36 pm
Значит оптимизации тут роли особой не играют. Скорее всего поможет только отключение проверок.
Возможно имеет смысл вычислять эти оффсеты один раз для всех 4 пикселов. Что-то вроде того, как Валерий предлагал. Надо будет попробовать.
может лучше мозги не трахать а попробовать вот это http://web.archive.org/web/20060718054020/http://www.acm.uiuc.edu/siggraph/workshops/wjarosz_convolution_2001.pdf (http://web.archive.org/web/20060718054020/http://www.acm.uiuc.edu/siggraph/workshops/wjarosz_convolution_2001.pdf)  ;)
Название: Re: Blur на разных ЯП.
Отправлено: valexey_u от Апрель 24, 2013, 09:15:25 pm
Значит оптимизации тут роли особой не играют. Скорее всего поможет только отключение проверок.
Возможно имеет смысл вычислять эти оффсеты один раз для всех 4 пикселов. Что-то вроде того, как Валерий предлагал. Надо будет попробовать.
может лучше мозги не трахать а попробовать вот это http://web.archive.org/web/20060718054020/http://www.acm.uiuc.edu/siggraph/workshops/wjarosz_convolution_2001.pdf (http://web.archive.org/web/20060718054020/http://www.acm.uiuc.edu/siggraph/workshops/wjarosz_convolution_2001.pdf)  ;)
Спасибо за ссылку конечно, но это офтопик. В данной теме (перечитай первое сообщение) мы сравниваем скорость разных ЯП на одном и том же алгоритме. Это бенчмарк по сути.

А обсуждение алгоритмов для быстрого размытия картинки ведется в теме "мы победили".

Впрочем под это не грех будет и отдельный топик завести.
Название: Re: Blur на разных ЯП.
Отправлено: DddIzer от Апрель 24, 2013, 09:18:17 pm
Спасибо за ссылку конечно, но это офтопик. В данной теме (перечитай первое сообщение) мы сравниваем скорость разных ЯП на одном и том же алгоритме. Это бенчмарк по сути.

А обсуждение алгоритмов для быстрого размытия картинки ведется в теме "мы победили".

Впрочем под это не грех будет и отдельный топик завести.
  ;) Да ну... это было бы оффтопиком если бы не большинство сообщений об усовершенствованиях - в том числе и ваше (на которое я ответил)...
Название: Re: Blur на разных ЯП.
Отправлено: valexey_u от Апрель 24, 2013, 09:20:13 pm
Спасибо за ссылку конечно, но это офтопик. В данной теме (перечитай первое сообщение) мы сравниваем скорость разных ЯП на одном и том же алгоритме. Это бенчмарк по сути.

А обсуждение алгоритмов для быстрого размытия картинки ведется в теме "мы победили".

Впрочем под это не грех будет и отдельный топик завести.
  ;) Да ну... это было бы оффтопиком если бы не большинство сообщений об усовершенствованиях - в том числе и ваше (на которое я ответил)...
Эти усовершенствования алгоритм не меняли, если угодно, это были всего лишь подсказки компилятору.
Название: Re: Blur на разных ЯП.
Отправлено: DddIzer от Апрель 24, 2013, 09:20:49 pm
 я к чему это... бенчмарктесь на здоровье но на качественной основе...
Название: Re: Blur на разных ЯП.
Отправлено: valexey_u от Апрель 24, 2013, 11:52:51 pm
Реаизовал алгоритм на javaScript'e. Поскольку прямо сейчас под рукой той, референсной машины нет, то все гонял на старом ноутбуке (2008 год, 32 бита. виста).

Результаты (js, и, для сравнения, ББ на этой машине):
js:
   time: 290 seconds
   fps : 3.45
BB/CP (DIV-оптимизация, 2D array):
   time: 454 seconds
   fps : 2.20

Итого, на числодробильных задачах (ну или по крайней мере на задачах обработки изображений) современный javascript в полтора раза быстрее чем BB. На 64-битной (референсной) системе отрыв, по идее, должен стать еще больше.

Код:
var N = 13;
var W = 640;
var H = 480;

function index(x,y,color) {
    return (W*y+x)*3+color;
}

var a = new Uint8Array(W*H*3);
var b = new Uint8Array(W*H*3);

var t1 = Date.now();

var frames = 1000;

for (var nn=0; nn<frames; nn++) {
    for (var i=0; i<N; i++) {
        for (var y=1; y<H-1; y++) {
            for (var x=1; x<W-1; x++) {
                for (var c=0; c<3; c++) {
                    b[index(x,y,c)] = (a[index(x,y+1,c)] + a[index(x,y-1,c)] + a[index(x+1,y,c)] + a[index(x-1,y,c)])/4;
                }
            }
        }
        for (var y=1; y<H-1; y++) {   
            for (var x=1; x<W-1; x++) { 
                for (var c=0; c<3; c++) {
                    a[index(x,y,c)] = (b[index(x,y+1,c)] + b[index(x,y-1,c)] + b[index(x+1,y,c)] + b[index(x-1,y,c)])/4;
                }
            }
        }
    }
}

var t2 = Date.now();
console.log((t2-t1)/1000);
console.log(frames/((t2-t1)/1000));
Название: Re: Blur на разных ЯП.
Отправлено: Губанов Сергей Юрьевич от Апрель 25, 2013, 11:41:49 am
Сделал цвета однобайтовыми, делаю блюр в трёх каналах, загружаю из картинки.

На i7 2600K уже с учётом трёх каналов:

N=5, R=10, time = 0.0140209 seconds, FPS = 71.3220977255383
N=6, R=12, time = 0.0166911 seconds, FPS = 59.912168760597
N=7, R=14, time = 0.0194411 seconds, FPS = 51.4374186645817
N=8, R=16, time = 0.0224343 seconds, FPS = 44.5746022831111

R - радиус размытия, N - количество фаз (за одну фазу делается два прохода, R = 2*N)

// Note! Need add reference to: WindowsBase, PresentationCore, System.Xaml
namespace Blur
{
class Program
{
private const int W = 640;
private const int H = 480;
private static System.Windows.Media.PixelFormat pixelFormat = System.Windows.Media.PixelFormats.Bgr24;

static void Main (string[] args)
{
byte[] a;
if (Load("input.jpg", out a))
{
const int N = 7;

byte[] b = new byte[a.Length];
System.Diagnostics.Stopwatch timer = new System.Diagnostics.Stopwatch();
timer.Start();
BlurX2(a, b, N);
timer.Stop();
double dt = timer.Elapsed.TotalSeconds;
System.Console.WriteLine("N={0}, R={1}, time = {2} seconds, FPS = {3}", N, 2*N, dt, 1.0/dt);
Save("output-R" + (2*N) + ".jpg", a);
System.Console.WriteLine("Ok");
System.Console.ReadLine();
}
}

public static unsafe void BlurX2 (byte[] A, byte[] B, int N)
{
const int dy = 3*W;
const int dx = 3;

fixed (byte* a = &A[0])
{
fixed (byte* b = &B[0])
{
for (int n = 0; n < N; n++)
{
for (int y = dy; y < dy*(H-1); y+=dy)
{
for (int x = dx; x < dx*(W-1); x+=dx)
{
int offset = y + x;
b[offset+0] = (byte)((a[offset-dy+0] + a[offset+dy+0] + a[offset-dx+0] + a[offset+dx+0]) / 4);
b[offset+1] = (byte)((a[offset-dy+1] + a[offset+dy+1] + a[offset-dx+1] + a[offset+dx+1]) / 4);
b[offset+2] = (byte)((a[offset-dy+2] + a[offset+dy+2] + a[offset-dx+2] + a[offset+dx+2]) / 4);
}
}
for (int y = dy; y < dy*(H-1); y+=dy)
{
for (int x = dx; x < dx*(W-1); x+=dx)
{
int offset = y + x;
a[offset+0] = (byte)((b[offset-dy+0] + b[offset+dy+0] + b[offset-dx+0] + b[offset+dx+0]) / 4);
a[offset+1] = (byte)((b[offset-dy+1] + b[offset+dy+1] + b[offset-dx+1] + b[offset+dx+1]) / 4);
a[offset+2] = (byte)((b[offset-dy+2] + b[offset+dy+2] + b[offset-dx+2] + b[offset+dx+2]) / 4);
}
}
}
}
}
}

public static bool Load (string fileName, out byte[] buffer)
{
buffer = null;
using (System.IO.FileStream s = new System.IO.FileStream(fileName, System.IO.FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.Read))
{
System.Windows.Media.Imaging.BitmapDecoder d = System.Windows.Media.Imaging.BitmapDecoder.Create(s,
System.Windows.Media.Imaging.BitmapCreateOptions.PreservePixelFormat,
System.Windows.Media.Imaging.BitmapCacheOption.Default);

System.Windows.Media.Imaging.BitmapFrame f = d.Frames[0];
if (f.PixelWidth != W)
{
System.Console.WriteLine("Unexpected width={0}, expected={1}", f.PixelWidth, W);
}
else if (f.PixelHeight != H)
{
System.Console.WriteLine("Unexpected height={0}, expected={1}", f.PixelHeight, H);
}
else if (f.Format != pixelFormat)
{
System.Console.WriteLine("Unexpected pixel format={0}, expected={1}", f.Format, pixelFormat);
}
else
{
buffer = new byte[W * H * 3];
f.CopyPixels(buffer, W * 3, 0);
}
}
return (buffer != null);
}

public static void Save (string fileName, byte[] buffer)
{
System.Windows.Media.Imaging.BitmapSource bm = System.Windows.Media.Imaging.BitmapSource.Create(
W, H, 300, 300, pixelFormat, null, buffer, W * 3);

using (System.IO.FileStream s = new System.IO.FileStream(fileName, System.IO.FileMode.Create))
{
System.Windows.Media.Imaging.JpegBitmapEncoder e = new System.Windows.Media.Imaging.JpegBitmapEncoder();
e.Frames.Add(System.Windows.Media.Imaging.BitmapFrame.Create(bm));
e.Save(s);
}
}
}
}

Прилагаю картинки (в архиве)
Название: Re: Blur на разных ЯП.
Отправлено: Geniepro от Апрель 25, 2013, 12:06:02 pm
Windows XP sp3, Pentium DualCore 1.6 GHz
GNAT2012       9.4 fps
TinyC 0.9.24   2.3 fps
VC2010        12.3 fps

Ada GNAT 2012
with Ada.Text_IO;       use Ada.Text_IO;
with Ada.Float_Text_IO; use Ada.Float_Text_IO;
with Ada.Real_Time; use Ada.Real_Time;

procedure BlurGnat is
   package Duration_IO is new Ada.Text_IO.Fixed_IO(Duration);
   use Duration_IO;

   width     : constant integer :=  640;
   height    : constant integer :=  480;
   blurRange : constant integer :=   13;
   frames    : constant integer := 1000;

   type Byte  is range 0 .. 255; for Byte'Size use 8;
   type Frame is array (0 .. (width*height*3-1)) of Byte;

   procedure Blur(inar : in Frame; outar : out Frame) is

      RED    : constant integer := 0;
      GREEN  : constant integer := 1;
      BLUE   : constant integer := 2;

      function index(x: integer; y: integer; color: integer) return integer is
      begin
         return width*y*3+x*3+color;
      end index;

   begin
      for y in 1..height-1-1 loop
         for x in 1..width-1-1 loop
            outar(index(x,y,RED)) := Byte(
                     (Integer(inar(index(x,y-1,RED)))   + Integer(inar(index(x,y+1,RED)))    +
                      Integer(inar(index(x-1,y,RED)))   + Integer(inar(index(x+1,y,RED))))   / 4);
            outar(index(x,y,GREEN)) := Byte(
                     (Integer(inar(index(x,y-1,GREEN))) + Integer(inar(index(x,y+1,GREEN)))  +
                      Integer(inar(index(x-1,y,GREEN))) + Integer(inar(index(x+1,y,GREEN)))) / 4);
            outar(index(x,y,BLUE)) := Byte(
                     (Integer(inar(index(x,y-1,BLUE)))  + Integer(inar(index(x,y+1,BLUE)))   +
                      Integer(inar(index(x-1,y,BLUE)))  + Integer(inar(index(x+1,y,BLUE))))  / 4);
         end loop;
      end loop;
   end Blur;

   inarr  : Frame;
   outarr : Frame;

   time_begin   : Time;
   time_elapsed : Duration;

begin
   for i in Frame'Range loop inarr(i) := 127; end loop;

   time_begin := Clock;

   for nn in 1..frames loop
      for i in 1..blurRange loop
         Blur(inarr,  outarr);
         Blur(outarr, inarr);
      end loop;
   end loop;

   time_elapsed := To_Duration(Clock - time_begin);

   Put("BlurGNAT: fps = "); Put(Float(frames)/Float(time_elapsed));
   Put(" time = "); Put(time_elapsed);

   Put_Line(" sec");

end BlurGnat;

TinyC 0.9.24
#include <stdio.h>
#include <time.h>

#define width       640
#define height      480
#define blurRange    13
#define frames      200

void Blur(char* inar, char* outar)
{
    #define RED   0
    #define GREEN 1
    #define BLUE  2

    #define index(x,y,color) ((width)*(y)*3+(x)*3+(color))

    int x, y;
    for (y=1; y<height-1; y++)
        for (x=1; x<width-1; x++) {
            outar[index(x,y,RED)]=
                ((int)inar[index(x,y-1,RED)]+
                 (int)inar[index(x,y+1,RED)]+
                 (int)inar[index(x-1,y,RED)]+
                 (int)inar[index(x+1,y,RED)]) >> 2;

            outar[index(x,y,GREEN)]=
                ((int)inar[index(x,y-1,GREEN)]+
                 (int)inar[index(x,y+1,GREEN)]+
                 (int)inar[index(x-1,y,GREEN)]+
                 (int)inar[index(x+1,y,GREEN)]) >> 2;

            outar[index(x,y,BLUE)]=
                ((int)inar[index(x,y-1,BLUE)]+
                 (int)inar[index(x,y+1,BLUE)]+
                 (int)inar[index(x-1,y,BLUE)]+
                 (int)inar[index(x+1,y,BLUE)]) >> 2;
        }
}

char in [width*height*3];
char out[width*height*3];

int main(void)
{
    int  nn, i;

    time_t begin, end;
    double seconds;

    time(&begin);

    for (nn=0; nn<frames; nn++)
    {
        for (i=0; i<blurRange; i++)
        {
            Blur(in,  out);
            Blur(out, in);
        }
    }

    time(&end);
    seconds = difftime(end, begin);
    printf("%f %d", (float)((double)frames)/seconds, (int)(seconds+0.5));
    return 0;
}
Название: Re: Blur на разных ЯП.
Отправлено: valexey_u от Апрель 25, 2013, 12:56:39 pm
Сделал цвета однобайтовыми, делаю блюр в трёх каналах, загружаю из картинки.
Предлагаю продолжить обсуждение алгоритмов тут: Сравнение blur-алгоритмов. (http://oberspace.dyndns.org/index.php/topic,485.0.html)
Название: Re: Blur на разных ЯП.
Отправлено: valexey_u от Апрель 25, 2013, 12:58:19 pm
Windows XP sp3, Pentium DualCore 1.6 GHz
GNAT2012       9.4 fps
TinyC 0.9.24   2.3 fps
VC2010        12.3 fps

Ada GNAT 2012
with Ada.Text_IO;       use Ada.Text_IO;
with Ada.Float_Text_IO; use Ada.Float_Text_IO;
with Ada.Real_Time; use Ada.Real_Time;

procedure BlurGnat is
   package Duration_IO is new Ada.Text_IO.Fixed_IO(Duration);
   use Duration_IO;

   width     : constant integer :=  640;
   height    : constant integer :=  480;
   blurRange : constant integer :=   13;
   frames    : constant integer := 1000;

   type Byte  is range 0 .. 255; for Byte'Size use 8;
   type Frame is array (0 .. (width*height*3-1)) of Byte;

   procedure Blur(inar : in Frame; outar : out Frame) is

      RED    : constant integer := 0;
      GREEN  : constant integer := 1;
      BLUE   : constant integer := 2;

      function index(x: integer; y: integer; color: integer) return integer is
      begin
         return width*y*3+x*3+color;
      end index;

   begin
      for y in 1..height-1-1 loop
         for x in 1..width-1-1 loop
            outar(index(x,y,RED)) := Byte(
                     (Integer(inar(index(x,y-1,RED)))   + Integer(inar(index(x,y+1,RED)))    +
                      Integer(inar(index(x-1,y,RED)))   + Integer(inar(index(x+1,y,RED))))   / 4);
            outar(index(x,y,GREEN)) := Byte(
                     (Integer(inar(index(x,y-1,GREEN))) + Integer(inar(index(x,y+1,GREEN)))  +
                      Integer(inar(index(x-1,y,GREEN))) + Integer(inar(index(x+1,y,GREEN)))) / 4);
            outar(index(x,y,BLUE)) := Byte(
                     (Integer(inar(index(x,y-1,BLUE)))  + Integer(inar(index(x,y+1,BLUE)))   +
                      Integer(inar(index(x-1,y,BLUE)))  + Integer(inar(index(x+1,y,BLUE))))  / 4);
         end loop;
      end loop;
   end Blur;

   inarr  : Frame;
   outarr : Frame;

   time_begin   : Time;
   time_elapsed : Duration;

begin
   for i in Frame'Range loop inarr(i) := 127; end loop;

   time_begin := Clock;

   for nn in 1..frames loop
      for i in 1..blurRange loop
         Blur(inarr,  outarr);
         Blur(outarr, inarr);
      end loop;
   end loop;

   time_elapsed := To_Duration(Clock - time_begin);

   Put("BlurGNAT: fps = "); Put(Float(frames)/Float(time_elapsed));
   Put(" time = "); Put(time_elapsed);

   Put_Line(" sec");

end BlurGnat;

TinyC 0.9.24
#include <stdio.h>
#include <time.h>

#define width       640
#define height      480
#define blurRange    13
#define frames      200

void Blur(char* inar, char* outar)
{
    #define RED   0
    #define GREEN 1
    #define BLUE  2

    #define index(x,y,color) ((width)*(y)*3+(x)*3+(color))

    int x, y;
    for (y=1; y<height-1; y++)
        for (x=1; x<width-1; x++) {
            outar[index(x,y,RED)]=
                ((int)inar[index(x,y-1,RED)]+
                 (int)inar[index(x,y+1,RED)]+
                 (int)inar[index(x-1,y,RED)]+
                 (int)inar[index(x+1,y,RED)]) >> 2;

            outar[index(x,y,GREEN)]=
                ((int)inar[index(x,y-1,GREEN)]+
                 (int)inar[index(x,y+1,GREEN)]+
                 (int)inar[index(x-1,y,GREEN)]+
                 (int)inar[index(x+1,y,GREEN)]) >> 2;

            outar[index(x,y,BLUE)]=
                ((int)inar[index(x,y-1,BLUE)]+
                 (int)inar[index(x,y+1,BLUE)]+
                 (int)inar[index(x-1,y,BLUE)]+
                 (int)inar[index(x+1,y,BLUE)]) >> 2;
        }
}

char in [width*height*3];
char out[width*height*3];

int main(void)
{
    int  nn, i;

    time_t begin, end;
    double seconds;

    time(&begin);

    for (nn=0; nn<frames; nn++)
    {
        for (i=0; i<blurRange; i++)
        {
            Blur(in,  out);
            Blur(out, in);
        }
    }

    time(&end);
    seconds = difftime(end, begin);
    printf("%f %d", (float)((double)frames)/seconds, (int)(seconds+0.5));
    return 0;
}
Интересно TinyC умеет inline?
А за реализацию на Аде - отдельное спасибо. Буду тестировать :-)
Название: Re: Blur на разных ЯП.
Отправлено: Geniepro от Апрель 25, 2013, 01:09:30 pm
Интересно TinyC умеет inline?
Похоже, что не умеет, потому что когда я вынес алгоритм самого блура в процедуру Blur, время работы выросло почти на 5%...

А за реализацию на Аде - отдельное спасибо. Буду тестировать :-)
Пока делал вариант на Аде -- половину времени потратил на то, что бы вывести результат в stdio -- с выводом чисел и всяких пользовательских там беда...
Название: Re: Blur на разных ЯП.
Отправлено: valexey_u от Апрель 25, 2013, 05:05:05 pm
Реаизовал алгоритм на javaScript'e. Поскольку прямо сейчас под рукой той, референсной машины нет, то все гонял на старом ноутбуке (2008 год, 32 бита. виста).

Результаты (js, и, для сравнения, ББ на этой машине):
js:
   time: 290 seconds
   fps : 3.45
BB/CP (DIV-оптимизация, 2D array):
   time: 454 seconds
   fps : 2.20

Итого, на числодробильных задачах (ну или по крайней мере на задачах обработки изображений) современный javascript в полтора раза быстрее чем BB. На 64-битной (референсной) системе отрыв, по идее, должен стать еще больше.

Потестировал на референсном ультрабуке:
js (32 bit):
   time: 246 seconds
   fps : 4.07
BB/CP (DIV-оптимизация, 2D array):
   time: 303 seconds
   fps : 3.30
js (64 bit):
   time: 1125 seconds
   fps : 0.89

Как ни странно, 64битная сборка node.js (движок там v8 - тот же что в google chrome) под 64битной же виндой работает в 4-5 раз медленнее на этой задче, чем 32битная.

Ну и js (32bit) и тут быстрее чем BlackBox, хотя разница уже не столь значительна.

Результаты тестов устойчивые, разлет не более чем на 3 секунды от теста к тесту.
Название: Re: Blur на разных ЯП.
Отправлено: akron1 от Апрель 25, 2013, 06:10:23 pm
Windows7 sp1, AMD Phenom 9650 2300MHz
TinyC 0.9.24      2.17 fps (реализация Geniepro)
Delphi-2010       4.32 fps
Delphi-2010       2.88 fps (Range checking)
BBCP              1.83 fps
XDS O2            1.82 fps
O-07M (Rifat)     0.37 fps
O-07/11 (akron1)  0.44 fps
O-07/11 (akron1)  0.55 fps (сдвиг вместо деления)

Везде, кроме TinyC 2D array

Название: Re: Blur на разных ЯП.
Отправлено: valexey_u от Апрель 25, 2013, 06:36:08 pm
Windows7 sp1, AMD Phenom 9650 2300MHz
TinyC 0.9.24      2.17 fps (реализация Geniepro)
Delphi-2010       4.32 fps
Delphi-2010       2.88 fps (Range checking)
BBCP              1.83 fps
XDS O2            1.82 fps
O-07M (Rifat)     0.37 fps
O-07/11 (akron1)  0.44 fps
O-07/11 (akron1)  0.55 fps (сдвиг вместо деления)

Везде, кроме TinyC 2D array

Можно исходники для Оберона-2 и Оберона-07/11?
Ну и делфи, до кучи.
Название: Re: Blur на разных ЯП.
Отправлено: akron1 от Апрель 25, 2013, 06:42:54 pm
Oberon-2
<*+ MAIN *>

MODULE Blur;

  IMPORT Out;

    CONST

        W = 640; W1 = 640 - 3;
        H = 480; H1 = 480 - 3;
        N = 13;
        Frames = 100;

    TYPE

        INTEGER = LONGINT;
        Plane = ARRAY W*3, H OF SHORTINT;

    VAR

        a, b : Plane;

  PROCEDURE Blur2DArray*;
  VAR
    f, n : INTEGER;
    x, y : INTEGER;
    color : INTEGER;
  BEGIN

    FOR f:=1 TO Frames DO
      FOR n:=1 TO N DO

        FOR y:=1 TO H-2 DO
          FOR x:=1 TO W-2 DO
            FOR color:=0 TO 2 DO
              b[x*3+color,y] := (a[x*3+color,y+1]+a[x*3+color,y-1]+a[(x-1)*3,y]+a[(x+1)*3,y]) DIV 4;
            END
          END
        END;

        FOR y:=1 TO H-2 DO
          FOR x:=1 TO W-2 DO
            FOR color:=0 TO 2 DO
              a[x*3+color,y] := (b[x*3+color,y+1]+b[x*3+color,y-1]+b[(x-1)*3,y]+b[(x+1)*3,y]) DIV 4;
            END
          END
        END
      END
    END;
  END Blur2DArray;

BEGIN
  Blur2DArray;
  Out.String("Done");
END Blur.

Oberon-07/11
MODULE Blur;

  IMPORT dt := DateTime, In, Out, RTL;

  CONST
    W = 640; W1 = 640 - 3;
    H = 480; H1 = 480 - 3;
    N = 13;
    Frames = 1;

  TYPE
    Plane = ARRAY W*3, H OF CHAR;

  VAR
    a, b:  Plane;
    time: LONGREAL;

  PROCEDURE Blur2DArray*;
  VAR
    f, n : INTEGER;
    x, y : INTEGER;
    color : INTEGER;
  BEGIN
    FOR f:=1 TO Frames DO
      FOR n:=1 TO N DO
        FOR y:=1 TO H-2 DO
          FOR x:=1 TO W-2 DO
            FOR color:=0 TO 2 DO
              b[x*3+color,y] := CHR((ORD(a[x*3+color,y+1])+ORD(a[x*3+color,y-1])+ORD(a[(x-1)*3,y])+ORD(a[(x+1)*3,y])) DIV 4);
            END
          END
        END;
        FOR y:=1 TO H-2 DO
          FOR x:=1 TO W-2 DO
            FOR color:=0 TO 2 DO
              a[x*3+color,y] := CHR((ORD(b[x*3+color,y+1])+ORD(b[x*3+color,y-1])+ORD(b[(x-1)*3,y])+ORD(b[(x+1)*3,y])) DIV 4);
            END
          END
        END
      END
    END;
  END Blur2DArray;

BEGIN
  In.Open;
  Out.Open;
  time := dt.Now();
  Blur2DArray;
  Out.FixReal(LONG(FLT(Frames))/((dt.Now() - time) * 86400.D0), 20, 5);
  In.Ln;
END Blur.

Oberon-07M
MODULE Blur;

  IMPORT c := Console;

  CONST
    W = 640; W1 = 640 - 3;
    H = 480; H1 = 480 - 3;
    N = 13;
    Frames = 10;

  TYPE
    Plane = ARRAY W*3, H OF CHAR;

  VAR
    a, b : Plane;
    time : INTEGER;

  PROCEDURE ["Kernel32.dll", "GetTickCount", 0] GetTickCount(): INTEGER;

  PROCEDURE Blur2DArray*;
  VAR
    f, n : INTEGER;
    x, y : INTEGER;
    color : INTEGER;
  BEGIN
    FOR f:=1 TO Frames DO
      FOR n:=1 TO N DO
        FOR y:=1 TO H-2 DO
          FOR x:=1 TO W-2 DO
            FOR color:=0 TO 2 DO
              b[x*3+color,y] := CHR((ORD(a[x*3+color,y+1])+ORD(a[x*3+color,y-1])+ORD(a[(x-1)*3,y])+ORD(a[(x+1)*3,y])) DIV 4);
            END
          END
        END;
        FOR y:=1 TO H-2 DO
          FOR x:=1 TO W-2 DO
            FOR color:=0 TO 2 DO
              a[x*3+color,y] := CHR((ORD(b[x*3+color,y+1])+ORD(b[x*3+color,y-1])+ORD(b[(x-1)*3,y])+ORD(b[(x+1)*3,y])) DIV 4);
            END
          END
        END
      END
    END;
  END Blur2DArray;

BEGIN
  time := GetTickCount();
  Blur2DArray;
  time := GetTickCount() - time;
  c.Int(time); c.Ln;
END Blur.

Dephi
program Blur;

{$APPTYPE CONSOLE}

uses
  SysUtils,
  Windows;

CONST
  W = 640; W1 = 640 - 3;
  H = 480; H1 = 480 - 3;
  NN = 13;
  Frames = 10;

TYPE
  Plane = ARRAY [0..W*3-1, 0..H-1] OF BYTE;

VAR
  a, b : Plane;

  PROCEDURE Blur2DArray;
  VAR
      f, n : INTEGER;
      x, y : INTEGER;
      color : INTEGER;
      i: INTEGER;
  BEGIN
    FOR f:=1 TO Frames DO BEGIN
      FOR n:=1 TO NN DO BEGIN
        FOR y:=1 TO H-2 DO BEGIN
          FOR x:=1 TO W-2 DO BEGIN
            FOR color:=0 TO 2 DO BEGIN
              b[x*3+color,y] := (a[x*3+color,y+1]+a[x*3+color,y-1]+a[(x-1)*3,y]+a[(x+1)*3,y]) DIV 4;
            END
          END
        END;
        FOR y:=1 TO H-2 DO BEGIN
          FOR x:=1 TO W-2 DO BEGIN
            FOR color:=0 TO 2 DO BEGIN
              a[x*3+color,y] := (b[x*3+color,y+1]+b[x*3+color,y-1]+b[(x-1)*3,y]+b[(x+1)*3,y]) DIV 4;
            END
          END
        END
      END
    END;
  END;

var t: Cardinal;
begin
  try
    t := GetTickCount;
    Blur2DArray;
    t := GetTickCount - t;
    Write((Frames/t*1000):20:5);
    Readln;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.
Название: Re: Blur на разных ЯП.
Отправлено: valexey_u от Апрель 25, 2013, 06:46:46 pm
Oberon-2
...
Oberon-07/11
...
Oberon-07M
...
Delphi
Спасибо, буду гонять (хотя до Delphi скорее всего не доберусь).
Название: Re: Blur на разных ЯП.
Отправлено: Valery Solovey от Апрель 25, 2013, 07:20:30 pm
Ну так как, дала моя ручная оптимизация какой-нибудь результат?
Название: Re: Blur на разных ЯП.
Отправлено: valexey_u от Апрель 25, 2013, 07:25:12 pm
Ну так как, дала моя ручная оптимизация какой-нибудь результат?
Не добрался еще, но помню что надо добраться :-)
Название: Re: Blur на разных ЯП.
Отправлено: Geniepro от Апрель 25, 2013, 09:27:15 pm
Win7 32 bit, Pentium DualCore 2.6 GHz
GNAT 2012 15.5 fps
TinyCC 3.77 fps
VC2012 20.8 fps
Rust 0.6 10.6 fps

Код на Rust'е -- первый раз на нём пишу, хз что надо тут делать, что бы шустро вычислялось...
extern mod std;
use std::time::precise_time_s;

fn index(x: uint, y: uint, color: uint) -> uint {
    (640*y + x)*3 + color
}

fn Blur(inar: &mut [u8], outar: &mut [u8]) {
    for uint::range(1, 480-2) |y| {
        for uint::range(1, 640-2) |x| {
            outar[index(x, y, 0)]= (
                ((inar[index(x, y-1, 0)] as uint) +
                 (inar[index(x, y+1, 0)] as uint) +
                 (inar[index(x-1, y, 0)] as uint) +
                 (inar[index(x+1, y, 0)] as uint)) >> 2) as u8;
            outar[index(x, y, 1)]= (
                ((inar[index(x, y-1, 1)] as uint) +
                 (inar[index(x, y+1, 1)] as uint) +
                 (inar[index(x-1, y, 1)] as uint) +
                 (inar[index(x+1, y, 1)] as uint)) >> 2) as u8;
            outar[index(x, y, 2)]= (
                ((inar[index(x, y-1, 2)] as uint) +
                 (inar[index(x, y+1, 2)] as uint) +
                 (inar[index(x-1, y, 2)] as uint) +
                 (inar[index(x+1, y, 2)] as uint)) >> 2) as u8;
        }
    }
}

fn timeit(f: &fn()) -> float {
    let start = precise_time_s();
    f();
    let stop = precise_time_s();
    stop - start
}

fn main() {
    let blurRange  : uint =  13;
    let frames     : uint = 1000;
    let mut inarr  = [127u8, ..(640*480*3)];
    let mut outarr = [  0u8, ..(640*480*3)];

    let time = do timeit {
        for uint::range(1, frames) |_nn| {
            for uint::range(1, blurRange) |_i| {
                Blur(inarr,  outarr);
                Blur(outarr, inarr);
            }
        } };
   
    io::println(fmt!("blur_rust: fps %? time %? sec", ((frames as float)/time), time));
}
Название: Re: Blur на разных ЯП.
Отправлено: ilovb от Апрель 26, 2013, 07:33:01 am
DIzer, не желаете эйфорию испытать?
Название: Re: Blur на разных ЯП.
Отправлено: Geniepro от Апрель 26, 2013, 08:26:01 am
WinXP sp3 Pentium DualCore 1.6 GHz
C# VS2010 .NET 4.0 3.8 fps
F# VS2010 .NET 4.0 10.9 fps

На этом же ПК до этого у меня были такие результаты:

GNAT2012       9.4 fps
TinyC 0.9.24   2.3 fps
VC2010        12.3 fps

Результаты ваще удивительные:
программа на сишарпе в три раза медленнее, чем на С++ (видимо из-за проверок выхода за границы массивов);
однако программа на F# почти догнала сишную (хотя её стоит лучше проверить -- на реальных фотках, а то хз правильно ли она работает)

C#:
using System;

namespace BlurCS
{
    class Program
    {
        const  uint width     = 640,
                    height    = 480,
                    blurRange =  13,
                    frames    =  20;

        static Byte[] inarr   = new Byte[width*height*3],
                      outarr  = new Byte[width*height*3];
       
        enum Color: uint
        {
            RED = 0,
            GREEN,
            BLUE
        }

        static uint index(uint x, uint y, Color color)
        {
            return 3*(width*y + x) + (uint)color;
        }

        static void Blur(ref Byte[] inar, ref Byte[] outar)
        {
            for (uint y=1; y<height-1; y++)
            {
                for (uint x=1; x<width-1; x++)
                {
                    outar[index(x, y, Color.RED)]= (Byte)(
                        ((uint)inar[index(x, y-1, Color.RED)]+
                         (uint)inar[index(x, y+1, Color.RED)]+
                         (uint)inar[index(x-1, y, Color.RED)]+
                         (uint)inar[index(x+1, y, Color.RED)]) >> 2);
                    outar[index(x, y, Color.GREEN)]= (Byte)(
                        ((uint)inar[index(x, y-1, Color.GREEN)]+
                         (uint)inar[index(x, y+1, Color.GREEN)]+
                         (uint)inar[index(x-1, y, Color.GREEN)]+
                         (uint)inar[index(x+1, y, Color.GREEN)]) >> 2);
                    outar[index(x, y, Color.BLUE)]= (Byte)(
                        ((uint)inar[index(x, y-1, Color.BLUE)]+
                         (uint)inar[index(x, y+1, Color.BLUE)]+
                         (uint)inar[index(x-1, y, Color.BLUE)]+
                         (uint)inar[index(x+1, y, Color.BLUE)]) >> 2);
                }
            }
        }

        static void Main(string[] args)
        {
            System.Diagnostics.Stopwatch timer = new System.Diagnostics.Stopwatch();
            timer.Reset(); timer.Start();

            for (uint nn=0; nn<frames; nn++)
            {
                for (uint i=0; i<blurRange; i++)
                {
                    Blur(ref inarr,  ref outarr);
                    Blur(ref outarr, ref inarr);
                }
            }

            timer.Stop();
            double dt = timer.Elapsed.TotalSeconds;

            System.Console.WriteLine("BlurC#: FPS = {0:##.##} time = {1:#.#} sec", (frames / dt), dt);
        }
    }
}

F#:
let width    : int = 640
let height   : int = 480
let blurRange: int =  13
let frames   : int = 100

let inarr:  byte array = Array.create     (3*width*height) 127uy
let outarr: byte array = Array.zeroCreate (3*width*height)

let Blur(inar: byte array ref, outar: byte array ref) =
   
    let inline index x y color = 3*(width*y + x) + color

    for y = 1 to height-2 do
        for x = 1 to width-2 do
            Array.set !outar (index x y 0)
                            (byte(
                                (int (!inar).[index   x (y-1) 0] +
                                 int (!inar).[index   x (y+1) 0] +
                                 int (!inar).[index (x-1) y   0] +
                                 int (!inar).[index (x+1) y   0]) / 2))

do  let timer = new System.Diagnostics.Stopwatch()
    timer.Reset(); timer.Start()

    for nn = 1 to frames do
        for i = 1 to blurRange do
            Blur(ref inarr,  ref outarr)
            Blur(ref outarr, ref inarr)

    timer.Stop()
    let dt = timer.Elapsed.TotalSeconds

    System.Console.WriteLine("BlurF#: FPS = {0:##.##} time = {1:#.#} sec", (float frames / dt), dt)
Название: Re: Blur на разных ЯП.
Отправлено: Geniepro от Апрель 26, 2013, 08:38:19 am
Результаты ваще удивительные:
программа на сишарпе в три раза медленнее, чем на С++ (видимо из-за проверок выхода за границы массивов);
однако программа на F# почти догнала сишную (хотя её стоит лучше проверить -- на реальных фотках, а то хз правильно ли она работает)

Ларчик просто открывался -- в программе на F# была ошибка -- обрабатывался только 1 цвет )))

WinXP sp3 Pentium DualCore 1.6 GHz
C# VS2010 .NET 4.0 3.8 fps
F# VS2010 .NET 4.0 2.8 fps

На этом же ПК до этого у меня были такие результаты:

GNAT2012       9.4 fps
TinyC 0.9.24   2.3 fps
VC2010        12.3 fps

Исправленный вариант на F#:
let width    : int = 640
let height   : int = 480
let blurRange: int =  13
let frames   : int = 100

let inarr:  byte array = Array.create     (3*width*height) 127uy
let outarr: byte array = Array.zeroCreate (3*width*height)

let Blur(inar: byte array ref, outar: byte array ref) =
   
    let index x y color = 3*(width*y + x) + color

    for y = 1 to height-2 do
        for x = 1 to width-2 do
            for c = 0 to 2 do
                Array.set !outar (index x y c)
                                (byte((int (!inar).[index   x (y-1) c] +
                                       int (!inar).[index   x (y+1) c] +
                                       int (!inar).[index (x-1) y   c] +
                                       int (!inar).[index (x+1) y   c]) / 2))

do  let timer = new System.Diagnostics.Stopwatch()
    timer.Reset(); timer.Start()

    for nn = 1 to frames do
        for i = 1 to blurRange do
            Blur(ref inarr,  ref outarr)
            Blur(ref outarr, ref inarr)

    timer.Stop()
    let dt = timer.Elapsed.TotalSeconds

    System.Console.WriteLine("BlurF#: FPS = {0:##.##} time = {1:#.#} sec", (float frames / dt), dt)
Название: Re: Blur на разных ЯП.
Отправлено: Geniepro от Апрель 26, 2013, 08:46:32 am
Какой-то не очень компилятор у F# -- не может развернуть простейший цикл. Развернул вручную -- fps поднялся 22% и составил 3.37 (был 2.8).
Всё же от сишарпа отстаёт на 13%...

F#:let width    : int = 640
let height   : int = 480
let blurRange: int =  13
let frames   : int = 100

let inarr:  byte array = Array.create     (3*width*height) 127uy
let outarr: byte array = Array.zeroCreate (3*width*height)

let Blur(inar: byte array ref, outar: byte array ref) =
   
    let index x y color = 3*(width*y + x) + color

    for y = 1 to height-2 do
        for x = 1 to width-2 do
            Array.set !outar (index x y 0)
                            (byte((int (!inar).[index   x (y-1) 0] +
                                   int (!inar).[index   x (y+1) 0] +
                                   int (!inar).[index (x-1) y   0] +
                                   int (!inar).[index (x+1) y   0]) / 2))
            Array.set !outar (index x y 1)
                            (byte((int (!inar).[index   x (y-1) 1] +
                                   int (!inar).[index   x (y+1) 1] +
                                   int (!inar).[index (x-1) y   1] +
                                   int (!inar).[index (x+1) y   1]) / 2))
            Array.set !outar (index x y 2)
                            (byte((int (!inar).[index   x (y-1) 2] +
                                   int (!inar).[index   x (y+1) 2] +
                                   int (!inar).[index (x-1) y   2] +
                                   int (!inar).[index (x+1) y   2]) / 2))

do  let timer = new System.Diagnostics.Stopwatch()
    timer.Reset(); timer.Start()

    for nn = 1 to frames do
        for i = 1 to blurRange do
            Blur(ref inarr,  ref outarr)
            Blur(ref outarr, ref inarr)

    timer.Stop()
    let dt = timer.Elapsed.TotalSeconds

    System.Console.WriteLine("BlurF#: FPS = {0:##.##} time = {1:#.#} sec", (float frames / dt), dt)
Название: Re: Blur на разных ЯП.
Отправлено: Romiras от Апрель 26, 2013, 09:12:31 am
Интересно, у кого есть оптимизирующий компилятор OOC, может ли проверить результат кода на Обероне-2?
Название: Re: Blur на разных ЯП.
Отправлено: Romiras от Апрель 26, 2013, 09:32:00 am
При замене кода
FOR y:=1 TO H-2 DO
FOR x:=1 TO W-2 DO
FOR color:=0 TO 2 DO
b[x*3+color,y] := SHORT(SHORT((a[x*3+color,y+1]+a[x*3+color,y-1]+a[(x-1)*3,y]+a[(x+1)*3,y]) DIV 4));
END
END
END;
на такой:
FOR y:=1 TO H-2 DO
FOR x:=1 TO W-2 DO
v := x*3; va := a[v - 3,y] + a[v + 3,y];
b[v,y] := SHORT(SHORT(ASH(
a[v,y+1]+
a[v,y-1]+
va
, -2)));
INC(v);
b[v,y] := SHORT(SHORT(ASH(
a[v,y+1]+
a[v,y-1]+
va
, -2)));
INC(v);
b[v,y] := SHORT(SHORT(ASH(
a[v,y+1]+
a[v,y-1]+
va
, -2)));
END
END;
Получаю дополнительное уменьшение времени выполнения почти на 40%.

Только гарантировать верность вычислений подтвердить не могу: на картинке не проверял.
Название: Re: Blur на разных ЯП.
Отправлено: DddIzer от Апрель 26, 2013, 11:55:54 am
DIzer, не желаете эйфорию испытать?
Не желаю участвовать в коллективном маразме (если состояние эйфории Алексея я еще могу понять, но  лично мне  моча глаза не застилает).. но это ИМХО , конечно...
Название: Re: Blur на разных ЯП.
Отправлено: valexey_u от Апрель 26, 2013, 12:10:37 pm
DIzer, не желаете эйфорию испытать?
Не желаю участвовать в коллективном маразме (если состояние эйфории Алексея я еще могу понять, но  лично мне  моча глаза не застилает).. но это ИМХО , конечно...
Ну, предложи другой конкретный алгоритм для бенчмарка. Он должен быть просто и короток в реализации.

Конкретный алгоритм - это значит покажи референсную реализацию его на любом императивном языке.
Название: Re: Blur на разных ЯП.
Отправлено: DddIzer от Апрель 26, 2013, 12:28:24 pm

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

Конкретный алгоритм - это значит покажи референсную реализацию его на любом императивном языке.
да любой другой... хоть решето Эратосфена...,или вычисления знаков числа Пи, Дело ведь не в этом..Я гнусно намекаю  на следующее
 ну ладно понравилось ЛИЧНО ВАМ слово Блер (с какого перепоя не мне судить). Захотели вы его реализовать... ну вызвался Сергей в качестве реализатора...
вопрос с какого перепоя Блером называется свертка с ядром ({0,1,0},{1,0,1},{0,1,0})/4 а не  ({1,1,1},{1,0,1},{1,1,1})/8... с какого будуна апликация сверток (повторение свертки N раз) ведет напрямую к увеличению ее радиуса  (по факту ширине окна усреднения). Просто посмотрите на ссылку ( это ведет главным образом к приближению к гауссовскому распределению  (радиальной симметричности), и на картинке видно, что больше N=6 - особого смысла выполнять итерации нет)... короче... не охота быть лошарой ми кантарой...
Название: Re: Blur на разных ЯП.
Отправлено: Geniepro от Апрель 26, 2013, 12:36:34 pm
DIzer, не желаете эйфорию испытать?
Не желаю участвовать в коллективном маразме (если состояние эйфории Алексея я еще могу понять, но  лично мне  моча глаза не застилает).. но это ИМХО , конечно...

Не вижу никакого маразма. Лично мне было интересно проверить некоторые моменты сгенерированного машинного кода для одного и того же алгоритма у разных компиляторов интересующих меня языков -- я и проверил. А какой именно там алгоритм -- правильный это блур или не очень -- мне пофигу... :D
Название: Re: Blur на разных ЯП.
Отправлено: DddIzer от Апрель 26, 2013, 12:40:48 pm


Не вижу никакого маразма. Лично мне было интересно....
А лично мне эта х..я не интересна...  - лично я не вижу никаких преимуществ у нее  перед тем же решетом, с одной стороны, а с другой стороны.. доказывать ПОНИМАЮЩЕМУ человеку что  это не х..я сложнее.. но это ИМХО
Название: Re: Blur на разных ЯП.
Отправлено: Geniepro от Апрель 26, 2013, 12:56:49 pm
У решета Эратосфена есть возможность оптимизации, которая может радикально его ускорить -- использование битовых массивов. Эта реализация может быть невозможной или крайне неэффективной в языках достаточно высокого уровня -- выше Си...
Название: Re: Blur на разных ЯП.
Отправлено: DddIzer от Апрель 26, 2013, 12:58:44 pm
У решета Эратосфена есть возможность оптимизации, которая может радикально его ускорить -- использование битовых массивов. Эта реализация может быть невозможной или крайне неэффективной в языках достаточно высокого уровня -- выше Си...
Конгениально , Геннадий (поправьте если ошибаюсь)... то же самое можно сказать и про текущий алгоритм, если в яп нет операции побитового сдвига...  ;)
Название: Re: Blur на разных ЯП.
Отправлено: valexey_u от Апрель 26, 2013, 01:04:03 pm
Спокойно народ. Этот бенчмарк будет подан под соусом - выбор инструмента в условиях хакатона (то есть в условиях когда времени нет, мозга нет, организм в шоке, зато есть ИДЕЯ, и нужно слепить прототип реализации этой идеи за короткое время).

Решето, вычисление Пи, функция Аккермана - идут лесом. Ибо не профиль.
Название: Re: Blur на разных ЯП.
Отправлено: DddIzer от Апрель 26, 2013, 01:06:07 pm

Решето, вычисление Пи, функция Аккермана - идут лесом. Ибо не профиль.
а что профиль.. почему БЛЕР.. а не просто дымчатый фон который генерируется за один проход...
Название: Re: Blur на разных ЯП.
Отправлено: DddIzer от Апрель 26, 2013, 01:08:25 pm
Спокойно народ. Этот бенчмарк будет подан под соусом
вот именно это и не нравится.... соус не соответствует блюду... и сделан из некачественных продуктов.. порубленный и смешанных "китайскими лохами"
Название: Re: Blur на разных ЯП.
Отправлено: valexey_u от Апрель 26, 2013, 01:14:23 pm

Решето, вычисление Пи, функция Аккермана - идут лесом. Ибо не профиль.
а что профиль.. почему БЛЕР.. а не просто дымчатый фон который генерируется за один проход...
Потому что ИДЕЯ. Фикс :-)

Ты дымчатый фон предполагаешь статичным? Генерацию через какой-нибудь perlin noise?
Название: Re: Blur на разных ЯП.
Отправлено: DddIzer от Апрель 26, 2013, 01:25:12 pm

Решето, вычисление Пи, функция Аккермана - идут лесом. Ибо не профиль.
а что профиль.. почему БЛЕР.. а не просто дымчатый фон который генерируется за один проход...
Потому что ИДЕЯ. Фикс :-)

Ты дымчатый фон предполагаешь статичным? Генерацию через какой-нибудь perlin noise?
я вам предлагал... сначала поработать со статикой.. (картинка не меняется от кадра к кадру)... для того что бы можно было либо сделать какие то выводы.. либо наметить путь дальнейших исследований... но касаемо конкретного ответа, на конкретный вопрос... как вам понравится эффект наложения дымчатой текстуры.. с  трансформацией ее от кадра к кадру (например, по синусоиде)?
Название: Re: Blur на разных ЯП.
Отправлено: Geniepro от Апрель 26, 2013, 01:28:17 pm
Конгениально , Геннадий (поправьте если ошибаюсь)...
Евгений.

то же самое можно сказать и про текущий алгоритм, если в яп нет операции побитового сдвига...  ;)
Даже если в языке нет операции побитового сдвига, то стыдно компилятору этого языка не суметь соптимизировать целочисленное умножение/деление на степень двойки в битовый сдвиг. Это тоже может быть показателем качества реализации языка...
Название: Re: Blur на разных ЯП.
Отправлено: valexey_u от Апрель 26, 2013, 01:33:09 pm
как вам понравится эффект наложения дымчатой текстуры.. с  трансформацией ее от кадра к кадру (например, по синусоиде)?
Я наверно предпочту 3D вариацию perlin noise, либо 3D simplex noise.
Название: Re: Blur на разных ЯП.
Отправлено: Geniepro от Апрель 26, 2013, 01:33:42 pm
Спокойно народ. Этот бенчмарк будет подан под соусом - выбор инструмента в условиях хакатона (то есть в условиях когда времени нет, мозга нет, организм в шоке, зато есть ИДЕЯ, и нужно слепить прототип реализации этой идеи за короткое время).
Непонятно, как такой соус может проканать -- ведь решения на других языках тут предлагались вовсе не в условиях хакатоновского стресса.

В таких условиях -- какой инструмент лучше знаешь, на том быстрее и решишь задачу (слепишь прототип)...

Вообще, в чём идея той серии статей про Оберон -- популяризовать его или совсем уже ниже плинтуса опустить? )))

ЗЫ. Да, и пора бы тебе уже привести на этот форум саму Надю! А то чо тут одни мужики собрались???
Название: Re: Blur на разных ЯП.
Отправлено: Geniepro от Апрель 26, 2013, 01:34:59 pm
как вам понравится эффект наложения дымчатой текстуры.. с  трансформацией ее от кадра к кадру (например, по синусоиде)?
Надеюсь, мои глаза такого гипнотизирующего эффекта никогда не увидят -- болеть начнут на второй секунде )))
Название: Re: Blur на разных ЯП.
Отправлено: Kemet от Апрель 26, 2013, 01:36:34 pm
Цитировать
Plane = ARRAY W*3, H OF SHORTINT;
Видимо, для Оберонов/КП правильный массив должен выглядеть как
Цитировать
Plane = ARRAY H, W*3 OF SHORTINT;
и результат тогда будет несколько другой
Название: Re: Blur на разных ЯП.
Отправлено: valexey_u от Апрель 26, 2013, 01:47:30 pm
Спокойно народ. Этот бенчмарк будет подан под соусом - выбор инструмента в условиях хакатона (то есть в условиях когда времени нет, мозга нет, организм в шоке, зато есть ИДЕЯ, и нужно слепить прототип реализации этой идеи за короткое время).
Непонятно, как такой соус может проканать -- ведь решения на других языках тут предлагались вовсе не в условиях хакатоновского стресса.
Это то как раз просто - чем наивней реализация, тем она лучше :-)
Ну и опять таки - любое усовершенствование в реализации алгоритма на конкретном языке обязано быть перенесено во все другия ЯП, и протестировано. У нас не http://benchmarksgame.alioth.debian.org/ , у нас все раализации одинаковы будут. Если какое-то усовершенствование не влияет на производительность скажем кода С++, то оно туда не вносится, а если, при этом, оно влияет на производительность Оберон-кода, то в результате имеем 2 версии Оберон-кода - с наивной реализацией, и с оптимизированной. Тестируются обе версии.

По результатам можно будет сравнить как производительность всех реализаций, так и читабельность (а также вероятность доспутить ошибку в реализации в состоянии цейтнота). И уже на основе этого сделать какие-то выводы.

В таких условиях -- какой инструмент лучше знаешь, на том быстрее и решишь задачу (слепишь прототип)...
Не совсем так. Если ты даже прекрасно знаешь js, то быструю реализацию данного алгоритма ты все равно не напишешь. То есть придется тратить драгоценное время на поиск менее тривиальных методик блюра.

Вообще, в чём идея той серии статей про Оберон -- популяризовать его или совсем уже ниже плинтуса опустить? )))
Для начала донести до народа, что они вообще существуют. И вон, даже их бенчмаркают на ряду со всеми известными ЯП.

ЗЫ. Да, и пора бы тебе уже привести на этот форум саму Надю! А то чо тут одни мужики собрались???
Захочет - сама придет :-)
Название: Re: Blur на разных ЯП.
Отправлено: DddIzer от Апрель 26, 2013, 01:53:55 pm

Даже если в языке нет операции побитового сдвига, то стыдно компилятору этого языка не суметь соптимизировать целочисленное умножение/деление на степень двойки в битовый сдвиг. Это тоже может быть показателем качества реализации языка...
не знаю как насчет сдвига.. но  в той же эйфории целочисленное деление (вычисление остатка) может применяться ко всем членам последовательности (как целочисленным так  и нет) -обобщенка..  ну не факт, что кто то будет оптимизировать это в общем случае...
Название: Re: Blur на разных ЯП.
Отправлено: DddIzer от Апрель 26, 2013, 01:54:40 pm
Евгений.
  :( Извините.. буду знать.
Название: Re: Blur на разных ЯП.
Отправлено: DddIzer от Апрель 26, 2013, 02:02:30 pm
Непонятно, как такой соус может проканать -- ведь решения на других языках тут предлагались вовсе не в условиях хакатоновского стресса.

Вот это и обидно.. если Блероманию.. можно списать  хакатоновый стресс.. и  идею фикс... , то х..ню от кучи здоровых  мужиков у которых есть время разобраться.. - нет.. но это имхо..Впрочем, хотя уровень  средний харбровских статей около плинтуса.. лично мне не охота вносить свой СОЗНАТЕЛЬНЫЙ вклад в увеличении энтропии.. Кроме того есть небольшая вероятность что можно напороться на специалиста.. - который скажет - "ну и уроды..."
Название: Re: Blur на разных ЯП.
Отправлено: valexey_u от Апрель 26, 2013, 02:09:57 pm
Непонятно, как такой соус может проканать -- ведь решения на других языках тут предлагались вовсе не в условиях хакатоновского стресса.

Вот это и обидно.. если Блероманию.. можно списать  хакатоновый стресс.. и  идею фикс... , то х..ню от кучи здоровых  мужиков у которых есть время разобраться.. - нет.. но это имхо..Впрочем, хотя уровень  средний харбровских статей около плинтуса.. лично мне не охота вносить свой СОЗНАТЕЛЬНЫЙ вклад в увеличении энтропии.. Кроме того есть небольшая вероятность что можно напороться на специалиста.. - который скажет - "ну и уроды..."

Еще раз - мы эмулируем разработку и реализацию алгоритма в условиях хакатона. В этой теме (вот конкретно в этой) не ведется дискуссия о качестве самого алгоритма. Мы тут лишь смотрим как разные ЯП себя ведут на наивнейшем и кривейшем алгоритме размытия. Всё.

Если говорить о алгоритме, то в общем то Надя еще в начале недели нашла алгоритм (но не реализацию) который реализует размытие любой силы за O(W*H) (то есть от силы размытия не зависит, зависит только от размеров картинки). И я теперь себя чувствую дебилом, ибо я же ЗНАЮ эти методики, и там в общем то ничего нового для меня по сути нет. По идее, мог бы и прямо на хакатоне додуматься до такого. Так что свое ускорение в 10 раз мы скорее всего уже получили :-)
Название: Re: Blur на разных ЯП.
Отправлено: DddIzer от Апрель 26, 2013, 02:44:45 pm
Еще раз - мы эмулируем разработку и реализацию алгоритма в условиях хакатона.
Делайте что хотите... только уж определитесь.. бенчмарки вы собираетеь отсылать или что еще.. и непонятно.. нафиг условиях хакотона моделировать бенчмарки... ;) - короче,
 я не ПРОТИВ , я за то что бы усе было достойно и непротиворечиво...
Название: Re: Blur на разных ЯП.
Отправлено: Губанов Сергей Юрьевич от Апрель 26, 2013, 03:01:36 pm
вопрос с какого перепоя Блером называется свертка с ядром ({0,1,0},{1,0,1},{0,1,0})/4 а не  ({1,1,1},{1,0,1},{1,1,1})/8... с какого будуна апликация сверток (повторение свертки N раз) ведет напрямую к увеличению ее радиуса  (по факту ширине окна усреднения).

Почему я беру именно ({0,1,0},{1,0,1},{0,1,0})/4 объясняется очень просто.

Изображение можно "разгладить" до
0) среднего значения;
1) линейного градиента;
2) полинома второй степени по x и y;
3) третей степени;
и т. д.

Случай (0) не очень интересен. Минимальное нетривиальное "разглаживание" есть разглаживание до линейного градиента, то есть зануление вторых и более высоких производных. Двумерный разностный лапласиан:

Lf[y, x] = f[y-1, x] + f[y+1, x] + f[y, x-1] + f[y, x+1] - 4*f[y, x];

Зануляем Lf[y, x] = 0, получаем итерационную схему

f -> h:

h[y, x] = (f[y-1, x] + f[y+1, x] + f[y, x-1] + f[y, x+1]) / 4;

Если эту схему гонять много раз, то картинка будет превращаться в линейный градиент.

Можно взять квадрат оператора лапласа:

LLf[y, x] = f[-2 + y, x] + 2 f[-1 + y, -1 + x] - 8 f[-1 + y, x] + 2 f[-1 + y, 1 + x] + f[y, -2 + x] - 8 f[y, -1 + x] + 20 f[y, x] - 8 f[y, 1 + x] + f[y, 2 + x] + 2 f[1 + y, -1 + x] - 8 f[1 + y, x] + 2 f[1 + y, 1 + x] + f[2 + y, x];

занулив его

LLf[y, x] = 0

получить другую итерационную схему:

h[y, x] = (-f[-2 + y, x] - 2 f[-1 + y, -1 + x] + 8 f[-1 + y, x] - 2 f[-1 + y, 1 + x] - f[y, -2 + x] + 8 f[y, -1 + x] + 8 f[y, 1 + x] - f[y, 2 + x] - 2 f[1 + y, -1 + x] + 8 f[1 + y, x] - 2 f[1 + y, 1 + x] - f[2 + y, x]) / 20;

Если эту схему гонять много раз, то картинка будет превращаться в "кубический градиент".

Как-то так...
Название: Re: Blur на разных ЯП.
Отправлено: DddIzer от Апрель 26, 2013, 03:07:41 pm

Почему я беру именно ({0,1,0},{1,0,1},{0,1,0})/4 объясняется очень просто.

Если эту схему гонять много раз, то картинка будет превращаться в "кубический градиент".

Как-то так...
  почему не вариант Б - с 8 единицами как более аккуратное прилближение... кстати , если посмотрите на ссылку.. то там на картинке видно, что при N=6 (для нормального ядра УЖЕ получается практически гауссово размытие.. т.е. больше 6 раз прогонять свертку на ядре 3x3 - смысла нет)
Название: Re: Blur на разных ЯП.
Отправлено: Valery Solovey от Апрель 26, 2013, 03:34:51 pm
это если на передний план смотреть...
Название: Re: Blur на разных ЯП.
Отправлено: DddIzer от Апрель 26, 2013, 03:41:59 pm
это если на передний план смотреть...
а зачем нам туда смотреть.. мы должны смотреть(искажать) назад(задний план)... то что попало в фокус камеры (передний план) должно передаваться без искажений (или с минимальными)...
Название: Re: Blur на разных ЯП.
Отправлено: Valery Solovey от Апрель 26, 2013, 04:18:00 pm
Вот моя версия КП/ББ. На моём компе на N=13 работает две минуты.
MODULE WorkBlur;
IMPORT Log, Kernel, SYSTEM;

CONST W = 640; H = 480; (* размер кадра в пикселях *)
w = (W - 1) * 3; h = H -1; (* размер области кадра на обработке *)
F = 1000; (* кол-во кадров *)

PROCEDURE Do*(N : INTEGER);
VAR a1, a2 : POINTER TO ARRAY OF BYTE;
len : INTEGER;
f, n, x, y : INTEGER;
m, t, l, r, b : INTEGER;
time : LONGINT;
BEGIN
time := Kernel.Time();
len := W * H * 3;
NEW( a1, len );
NEW( a2, len );
f := 0;
WHILE f < F DO

n := 0;
WHILE n < N DO                                   (* x, y *)
t := 3;                                            (* 1, 0 *)
l := w - 3; m := l + 3; r := l + 6; (* 0, 1 ; 1, 1 ; 2, 1 *)
b := r + w;                                      (* 1, 2 *)

y := 1;
WHILE y < h DO
x := 3;
WHILE x < w DO
a2[m] := SHORT(SHORT(SYSTEM.LSH((a1[t] + a1[b] + a1[l] + a1[r]), -2)));
t := t + 1; l := l + 1; m := m + 1; r := r + 1; b := b + 1;
x := x + 1
(*INC(t); INC(l); INC(m); INC(r); INC(b);
INC(x)*)
END;
t := t + 6; l := l + 6; m := m + 6; r := r + 6; b := b + 6;
y := y + 1
(*INC(y)*)
END;

(*<-->*)

t := 3;
l := w - 3; m := l + 3; r := l + 6;
b := r + w;

y := 1;
WHILE y < h DO
x := 3;
WHILE x < w DO
a1[m] := SHORT(SHORT(SYSTEM.LSH((a2[t] + a2[b] + a2[l] + a2[r]), -2)));
t := t + 1; l := l + 1; m := m + 1; r := r + 1; b := b + 1;
x := x + 1
END;
t := t + 6; l := l + 6; m := m + 6; r := r + 6; b := b + 6;
y := y + 1
END;

n := n + 1
END;
f := f + 1
END;
Log.Int(SHORT(Kernel.Time() - time))
END Do;

END WorkBlur.
Название: Re: Blur на разных ЯП.
Отправлено: Valery Solovey от Апрель 26, 2013, 06:28:39 pm
Пока писал версию для двумерного массива, понял, что неправильно соптимизировал версию для одномерного.
Второй заход:
для N=13
одномерный массив - больше 1.5 минуты
двумерный - больше 3 минут

MODULE WorkBlur;
IMPORT Log, Kernel, SYSTEM;

CONST W = 640; H = 480; (* размер кадра в пикселях *)
ln = 1;
clr = 3;
w = (W - 1) * clr; h = H -1; (* размер области кадра на обработке *)
w2 = W * clr;
shift = -2;
F = 1000; (* кол-во кадров *)

PROCEDURE Do*(N : INTEGER);
VAR a1, a2 : POINTER TO ARRAY OF BYTE;
len : INTEGER;
f, n, x, y : INTEGER;
m : INTEGER;
time : LONGINT;
BEGIN
time := Kernel.Time();
len := W * H * clr;
NEW( a1, len );
NEW( a2, len );
f := 0;
WHILE f < F DO

n := 0;
WHILE n < N DO
m := w + 6;

y := 1;
WHILE y < h DO
x := 3;
WHILE x < w DO
a2[m] := SHORT(SHORT(SYSTEM.LSH(a1[m - w2] + a1[m - clr] + a1[m + clr] + a1[m + w2], shift)));
m := m + 1;
x := x + 1
END;
m := m + 6;
y := y + 1
END;

(*<-->*)

m := w + 6;

y := 1;
WHILE y < h DO
x := 3;
WHILE x < w DO
a1[m] := SHORT(SHORT(SYSTEM.LSH(a2[m - w2] + a2[m - clr] + a2[m + clr] + a2[m + w2], shift)));
m := m + 1;
x := x + 1
END;
m := m + 6;
y := y + 1
END;

n := n + 1
END;
f := f + 1
END;
Log.Int(SHORT(Kernel.Time() - time))
END Do;

PROCEDURE Do2*(N : INTEGER);
VAR  a1, a2 : POINTER TO ARRAY OF ARRAY OF BYTE;
len : INTEGER;
f, n, x, y : INTEGER;
time : LONGINT;
BEGIN
time := Kernel.Time();
NEW( a1, H, W * 3 );
NEW( a2, H, W * 3 );
f := 0;

WHILE f < F DO

n := 0;
WHILE n < N DO
y := 1;
WHILE y < h DO
x := 3;
WHILE x < w DO
a2[y, x] := SHORT(SHORT(SYSTEM.LSH(a1[y - ln, x] + a1[y, x - clr] + a1[y, x + clr] + a1[y + ln, x], shift)));
x := x + 1
END;
y := y + 1
END;

y := 1;
WHILE y < h DO
x := 3;
WHILE x < w DO
a1[y, x] := SHORT(SHORT(SYSTEM.LSH(a2[y - ln, x] + a2[y, x - clr] + a2[y, x + clr] + a2[y + ln, x], shift)));
x := x + 1
END;
y := y + 1
END;

n := n + 1
END;
f := f + 1
END;
Log.Int(SHORT(Kernel.Time() - time))
END Do2;

END WorkBlur.
Название: Re: Blur на разных ЯП.
Отправлено: valexey_u от Апрель 26, 2013, 06:37:42 pm
Пока писал версию для двумерного массива, понял, что неправильно соптимизировал версию для одномерного.
Второй заход:
для N=13
одномерный массив - больше 1.5 минуты
двумерный - больше 3 минут

Круто! А какие характеристики ноута?
Название: Re: Blur на разных ЯП.
Отправлено: Valery Solovey от Апрель 26, 2013, 06:42:20 pm
я это на большом компе запускал.

Проц. i3 3220. Остальное значение не имеет, мне кажется.
Название: Re: Blur на разных ЯП.
Отправлено: valexey_u от Апрель 26, 2013, 06:48:25 pm
я это на большом компе запускал.

Проц. i3 3220. Остальное значение не имеет, мне кажется.
Всё равно круто :-) (вообще говоря, тут еще шустрость памяти играет роль)

Доберусь до того ультрабука - затестю.

PS. И надо будет таки научиться работать с картинками в ББ (прочитать с диска, отобразить, записать на диск)
Название: Re: Blur на разных ЯП.
Отправлено: Valery Solovey от Апрель 26, 2013, 07:09:38 pm
Про память я уже подзабыл.
Помню, что Кингстон, тайминги 11.
Частота, возможно 1600

Название: Re: Blur на разных ЯП.
Отправлено: Valery Solovey от Апрель 26, 2013, 08:22:19 pm
нетбук асус 1215b.
Проц. AMD® APU E450 1.65GHz (dual core)
Память DDR3, одноканальная.

Провёл несколько тестов на одномерных массивах. Постепенно "отпускал" комп. от режима энергопотребления к максимальной производительности.
 658 - 783 - 385 - 385 (секунды)
Название: Re: Blur на разных ЯП.
Отправлено: ilovb от Апрель 26, 2013, 09:00:49 pm
Реаизовал алгоритм на javaScript'e. Поскольку прямо сейчас под рукой той, референсной машины нет, то все гонял на старом ноутбуке (2008 год, 32 бита. виста).

Результаты (js, и, для сравнения, ББ на этой машине):
js:
   time: 290 seconds
   fps : 3.45
BB/CP (DIV-оптимизация, 2D array):
   time: 454 seconds
   fps : 2.20

BB/CP (DIV-оптимизация, 2D array): ~428 s
LuaJit 2.0.1 (x86): ~197 s

local ffi = require 'ffi'

local W, H = 640, 480
local N, F = 13, 1000

local plane = ffi.typeof("uint8_t[?]")

local a, b = plane(W*H*3), plane(W*H*3)

local function index(x, y, c)
    return (x+y*W)*3 + c
end

local t1 = os.clock()

for f = 1, F do
    for n = 1, N do

        for y = 1, H-2 do
            for x = 1, W-2 do
                for c = 0, 2 do
                    b[index(x, y, c)] = bit.lshift(
                                a[index(x, y+1, c)]+
                                a[index(x, y-1, c)]+
                                a[index(x-1, y, c)]+
                                a[index(x+1, y, c)], 2)
                end
            end
        end

        for y = 1, H-2 do
            for x = 1, W-2 do
                for c = 0, 2 do
                    a[index(x, y, c)] = bit.lshift(
                                b[index(x, y+1, c)]+
                                b[index(x, y-1, c)]+
                                b[index(x-1, y, c)]+
                                b[index(x+1, y, c)], 2)
                end
            end
        end

    end
end

print(os.clock() - t1)

Core i3 M380 2.53GHz
Windows 7 64
Название: Re: Blur на разных ЯП.
Отправлено: fortran от Апрель 26, 2013, 09:02:10 pm
Версия на Fortran
program blur_bench
  implicit none
 
  integer, parameter :: width = 640, height = 480
  integer, parameter :: frames = 20, r = 13

  type pixel
    byte :: r, g, b
  end type

  integer :: i, j, f, n
  real :: t1, t2
  type(pixel), dimension(width,height) :: in, out
 
  call cpu_time(t1)

  do f = 1,frames
    do n = 1,r
      do j = 2,height-1
        do i = 2,width-1
          out(i,j)%r = (in(i-1,j)%r + in(i+1,j)%r + in(i,j-1)%r + in(i,j+1)%r) / 4
          out(i,j)%g = (in(i-1,j)%g + in(i+1,j)%g + in(i,j-1)%g + in(i,j+1)%g) / 4
          out(i,j)%b = (in(i-1,j)%b + in(i+1,j)%b + in(i,j-1)%b + in(i,j+1)%b) / 4
        end do
      end do
      do j = 2,height-1
        do i = 2,width-1
          in(i,j)%r = (out(i-1,j)%r + out(i+1,j)%r + out(i,j-1)%r + out(i,j+1)%r) / 4
          in(i,j)%g = (out(i-1,j)%g + out(i+1,j)%g + out(i,j-1)%g + out(i,j+1)%g) / 4
          in(i,j)%b = (out(i-1,j)%b + out(i+1,j)%b + out(i,j-1)%b + out(i,j+1)%b) / 4
        end do
      end do
    end do
  end do
 
  call cpu_time(t2)
  write (*,*) 'Time: ', t2-t1
  write (*,*) 'FPS: ', frames/(t2-t1)

end program
Название: Re: Blur на разных ЯП.
Отправлено: Valery Solovey от Апрель 26, 2013, 09:34:42 pm
Варианта на жабе не было?

через for-ы где-то на полсекунды быстрее работает, чем через while. Но всё равно где-то на 10 сек. медленнее ББ.
Проверял на десктопе, из IDE, без каких-либо ключей. жаба 7.

import java.io.IOException;
import java.io.InputStream;

public class TestBlur {

    private static int W = 640;
    private static int H = 480;

    private static int line = 1;
    private static int colour = 3;

    private static int w = (W - 1) * colour;
    private static int h = H - 1;

    private static int w2 = W + colour;
    private static int shift = 2;

    private static int F = 1000;

    private static void Do(int N) {
        long time = System.currentTimeMillis();
        int len = W * H * colour;
        byte a1[] = new byte[len];
        byte a2[] = new byte[len];
        int m;

        for (int f = 0; f < F; f++) {
            for (int n = 0; n < N; n++) {
                m = w + 6;
                for (int y = 1; y < h; y++) {
                    for (int x = 3; x < w; x++) {
                        a2[m] = (byte) ((a1[m - w2] + a1[m - colour] + a1[m + colour] + a1[m + w2] ) >> shift);
                        m++;
                    }
                    m = m + 6;
                }

                m = w + 6;
                for (int y = 1; y < h; y++) {
                    for (int x = 3; x < w; x++) {
                        a1[m] = (byte) ((a2[m - w2] + a2[m - colour] + a2[m + colour] + a2[m + w2] ) >> shift);
                        m++;
                    }
                    m = m + 6;
                }
            }
        }
        System.out.println(System.currentTimeMillis() - time);
    }

    private static void Do2(int N) {
        long time = System.currentTimeMillis();
        int len = W * H * colour;
        byte a1[] = new byte[len];
        byte a2[] = new byte[len];
        int m;

        int f, n;
        int x, y;

        f = 0;
        while (f < F) {
            n = 0;
            while (n < N) {
                m = w + 6;
                y = 1;
                while (y < h) {
                    x = 3;
                    while (x < w) {
                        a2[m] = (byte) ((a1[m - w2] + a1[m - colour] + a1[m + colour] + a1[m + w2] ) >> shift);
                        m++;
                        x++;
                    }
                    m = m + 6;
                    y++;
                }

                m = w + 6;
                y = 1;
                while (y < h) {
                    x = 3;
                    while (x < w) {
                        a1[m] = (byte) ((a2[m - w2] + a2[m - colour] + a2[m + colour] + a2[m + w2] ) >> shift);
                        m++;
                        x++;
                    }
                    m = m + 6;
                    y++;
                }

                n++;
            }
            f++;
        }
        System.out.println(System.currentTimeMillis() - time);
    }

    public static void main(String argv[]) {
        char ch = 'd';
        InputStream is = System.in;
        while (ch != 'q' || ch == 'Q') {
            System.out.print("Start test [1,2], [Q]uit > ");
            try {
                ch = (char) is.read();
                if (ch == '1') {
                    Do(13);
                } else if (ch == '2') {
                    Do2(13);
                }
            } catch (IOException e) {
                System.err.println("error: " + e.getMessage());
            }
        }
    }
}
Название: Re: Blur на разных ЯП.
Отправлено: ilovb от Апрель 26, 2013, 09:45:00 pm
...
Блин, перепутал.
rshift должен быть
Название: Re: Blur на разных ЯП.
Отправлено: Valery Solovey от Апрель 27, 2013, 01:18:14 am
Сделал версию на Лимбе, но что-то оно медленно работает...
То ли там особый подход нужен, то ли эмулятор там слабенький.
Для N=13 работало дольше 1:20. Правда, через полчаса после запуска меня заколебало, и я начал просмотр фильма. Возможно, это в некоторой степени повлияло на результат.
Название: Re: Blur на разных ЯП.
Отправлено: Kemet от Апрель 27, 2013, 04:44:44 am
В Блэкбоксе же ASH есть нормально работающий
Название: Re: Blur на разных ЯП.
Отправлено: Kemet от Апрель 27, 2013, 10:36:26 am
Глянул исходники компилятора Блэкбокса - DIV в нужных местах заменяется на математические сдвиги
Название: Re: Blur на разных ЯП.
Отправлено: Kemet от Апрель 27, 2013, 10:39:51 am
то бишь на арифметические
Название: Re: Blur на разных ЯП.
Отправлено: Valery Solovey от Апрель 27, 2013, 12:11:41 pm
Байт бывает отрицательным.
Цитировать
Глянул исходники компилятора Блэкбокса
А в каком именно модуле ББ это находится?
Название: Re: Blur на разных ЯП.
Отправлено: Kemet от Апрель 27, 2013, 12:23:01 pm
Байт бывает отрицательным.
Цитировать
Глянул исходники компилятора Блэкбокса
А в каком именно модуле ББ это находится?
CPB
Название: Re: Blur на разных ЯП.
Отправлено: Valery Solovey от Апрель 27, 2013, 12:55:11 pm
Да, спасибо. Я уже тоже нашёл.
Название: Re: Blur на разных ЯП.
Отправлено: Valery Solovey от Май 03, 2013, 04:34:52 pm
Так какие же результаты запусков программ на эталонной машине?
Название: Re: Blur на разных ЯП.
Отправлено: vlad от Май 04, 2013, 05:04:21 pm
Oberon-07/11

Кстати, к вопросу о совместимости разных реализаций. Приведенный пример не соответствует репорту языка синтаксически - пресловутые "лишние" точки с запятой. Могу долго рассказывать, что я об этом думаю... но не буду. Просто замечу.
Название: Re: Blur на разных ЯП.
Отправлено: akron1 от Май 04, 2013, 05:27:33 pm
Oberon-07/11

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

Цитата из репорта:

statement = [assignment | ProcedureCall | IfStatement | CaseStatement |
WhileStatement | RepeatStatement | ForStatement].
...
StatementSequence = statement {";" statement}.

Из этого следует, что statement может быть пустым, значит лишние ";" не являются ошибкой, они просто необязательны.
Название: Re: Blur на разных ЯП.
Отправлено: Berserker от Май 04, 2013, 06:19:36 pm
Цитировать
Могу долго рассказывать, что я об этом думаю... но не буду.
Если не затруднит, поясните пожалуйста, какой смысл иметь возможность использовать пустой оператор?
Название: Re: Blur на разных ЯП.
Отправлено: akron1 от Май 04, 2013, 06:36:23 pm
Например:

WHILE func() DO
(* пустой оператор *)
END

Где func -- функция с побочным эффектом, например читает данные из файла, выполняет их обработку и возвращает FALSE, если достигнут конец файла.
Название: Re: Blur на разных ЯП.
Отправлено: Berserker от Май 04, 2013, 07:17:25 pm
Такие вещи можно и в одну строку оформлять на мой взгляд.
WHILE ProcessNextFile() DO END; (* Обработали файлы *)
В руководстве от Гугла по С++, если не ошибаюсь, разрешают и так:
while (ProcessNextFile()) {}
Название: Re: Blur на разных ЯП.
Отправлено: vlad от Май 04, 2013, 09:20:53 pm
statement = [assignment | ProcedureCall | IfStatement | CaseStatement |
WhileStatement | RepeatStatement | ForStatement].
...
StatementSequence = statement {";" statement}.

Из этого следует, что statement может быть пустым, значит лишние ";" не являются ошибкой, они просто необязательны.

Не, не вижу - где может быть пустой statement?
Название: Re: Blur на разных ЯП.
Отправлено: akron1 от Май 04, 2013, 09:34:49 pm
Не, не вижу - где может быть пустой statement?

statement = [assignment | ProcedureCall | IfStatement | CaseStatement |
WhileStatement | RepeatStatement | ForStatement].


Квадратные скобки видишь?))
Название: Re: Blur на разных ЯП.
Отправлено: vlad от Май 04, 2013, 11:36:36 pm
Квадратные скобки видишь?))

Спасибо! :)
Название: Re: Blur на разных ЯП.
Отправлено: vlad от Май 05, 2013, 04:50:26 am
Если не затруднит, поясните пожалуйста, какой смысл иметь возможность использовать пустой оператор?

У меня была претензия не к пустому оператору, а к отсутствию (обязательному) точки с запятой перед END. akron1 указал на возможность пустого statement в грамматике (я этот момент упустил), так что опциональная точка с запятой допустима. Претензия снята, был не прав.
Название: Re: Blur на разных ЯП.
Отправлено: trurl от Май 07, 2013, 08:51:28 am
Поигрался в оптимизацию на BB.
Исходный вариант с Blur2DArray: 0.77 fps.
Переход к 3D (ARRAY W, H, 3 OF BYTE): 0.73 fps, зато обнаружились ошибки (пропущено +color).
DIV 4 вместо *0.25 : 1.4 fps.
Раскрутка цикла по color : 2.09 fps. (по идее здесь устраняются и проверки последнего индекса)
Выравнивание данных (ARRAY W, H, 4 OF BYTE): 2.48 fps.
Статический массив вместо динамического: 2.65 fps.
Отключение проверок: 2.73 fps.
Здесь фантазия иссякла.
Без выравнивания, но с отключеными проверками дает 2.54 fps, что чуть лучше, чем tcc (2.22 fps).
Название: Re: Blur на разных ЯП.
Отправлено: valexey_u от Май 07, 2013, 09:29:32 am
Поигрался в оптимизацию на BB.
Исходный вариант с Blur2DArray: 0.77 fps.
Переход к 3D (ARRAY W, H, 3 OF BYTE): 0.73 fps, зато обнаружились ошибки (пропущено +color).
DIV 4 вместо *0.25 : 1.4 fps.
Раскрутка цикла по color : 2.09 fps. (по идее здесь устраняются и проверки последнего индекса)
Выравнивание данных (ARRAY W, H, 4 OF BYTE): 2.48 fps.
Статический массив вместо динамического: 2.65 fps.
Отключение проверок: 2.73 fps.
Здесь фантазия иссякла.
Без выравнивания, но с отключеными проверками дает 2.54 fps, что чуть лучше, чем tcc (2.22 fps).
Исходники от экспериментов остались? Было бы полезно из выложить - чтобы другим велосипед не изобретать.
Название: Re: Blur на разных ЯП.
Отправлено: trurl от Май 07, 2013, 10:07:44 am
Здесь фантазия иссякла.
Семен Семеныч! Там же индексы в "неправильном" порядке!
Итого 3.5 fps или 4.7 fps с отключенными проверками.
MODULE TestBlur;
  IMPORT Kernel, Out:=StdLog;

  CONST
    W = 640;
    H = 480;
    N = 13;
    Frames = 100;

    RED = 0; GREEN=1; BLUE=2;

  TYPE
    Plane = ARRAY  H, W, 4 OF BYTE;
   
  VAR 
    a, b : Plane;

  PROCEDURE Blur*;
  VAR
    time1,time2 : LONGINT;     fps:REAL;
    f, n : INTEGER;
    x, y : INTEGER;
    color : INTEGER;
  BEGIN
    time1 := Kernel.Time();

    FOR f:=1 TO Frames DO
      FOR n:=1 TO N DO

        FOR y:= 1 TO H-2 DO
          FOR x:= 1 TO W-2 DO
              b[y,x][RED] := SHORT(SHORT((a[y,x + 1][RED] + a[y,x - 1][RED] + a[y - 1, x][RED] + a[y + 1, x][RED]) DIV 4));
              b[y,x][GREEN] := SHORT(SHORT((a[y,x + 1][GREEN] + a[y,x - 1][GREEN] + a[y - 1, x][GREEN] + a[y + 1, x][GREEN]) DIV 4));
              b[y,x][BLUE] := SHORT(SHORT((a[y,x + 1][BLUE] + a[y,x - 1][BLUE] + a[y - 1, x][BLUE] + a[y + 1, x][BLUE]) DIV 4));
          END
        END;

        FOR y:=1 TO H-2 DO
          FOR x:=1 TO W-2 DO
              a[y,x][RED] := SHORT(SHORT((b[y,x + 1][RED] + b[y,x - 1][RED] + b[y - 1, x][RED] + b[y + 1, x][RED]) DIV 4));
              a[y,x][GREEN] := SHORT(SHORT((b[y,x + 1][GREEN] + b[y,x - 1][GREEN] + b[y - 1, x][GREEN] + b[y + 1, x][GREEN]) DIV 4));
              a[y,x][BLUE] := SHORT(SHORT((b[y,x + 1][BLUE] + b[y,x - 1][BLUE] + b[y - 1, x][BLUE] + b[y + 1, x][BLUE]) DIV 4));
          END
        END

      END
    END;
    time2 := Kernel.Time();
    fps:=Frames*1000/(time2 - time1);
    Out.String("t="); Out.Real((time2 - time1)/1000);
    Out.String(" fps="); Out.Real(fps);
    Out.Ln;
  END Blur;

END TestBlur.

DevCompiler.CompileThis TestBlur!!
TestBlur.Blur
Название: Re: Blur на разных ЯП.
Отправлено: valexey_u от Май 07, 2013, 10:45:16 am
Здесь фантазия иссякла.
Семен Семеныч! Там же индексы в "неправильном" порядке!
Итого 3.5 fps или 4.7 fps с отключенными проверками.
MODULE TestBlur;
  IMPORT Kernel, Out:=StdLog;

  CONST
    W = 640;
    H = 480;
    N = 13;
    Frames = 100;

    RED = 0; GREEN=1; BLUE=2;

  TYPE
    Plane = ARRAY  H, W, 4 OF BYTE;
   
  VAR 
    a, b : Plane;

  PROCEDURE Blur*;
  VAR
    time1,time2 : LONGINT;     fps:REAL;
    f, n : INTEGER;
    x, y : INTEGER;
    color : INTEGER;
  BEGIN
    time1 := Kernel.Time();

    FOR f:=1 TO Frames DO
      FOR n:=1 TO N DO

        FOR y:= 1 TO H-2 DO
          FOR x:= 1 TO W-2 DO
              b[y,x][RED] := SHORT(SHORT((a[y,x + 1][RED] + a[y,x - 1][RED] + a[y - 1, x][RED] + a[y + 1, x][RED]) DIV 4));
              b[y,x][GREEN] := SHORT(SHORT((a[y,x + 1][GREEN] + a[y,x - 1][GREEN] + a[y - 1, x][GREEN] + a[y + 1, x][GREEN]) DIV 4));
              b[y,x][BLUE] := SHORT(SHORT((a[y,x + 1][BLUE] + a[y,x - 1][BLUE] + a[y - 1, x][BLUE] + a[y + 1, x][BLUE]) DIV 4));
          END
        END;

        FOR y:=1 TO H-2 DO
          FOR x:=1 TO W-2 DO
              a[y,x][RED] := SHORT(SHORT((b[y,x + 1][RED] + b[y,x - 1][RED] + b[y - 1, x][RED] + b[y + 1, x][RED]) DIV 4));
              a[y,x][GREEN] := SHORT(SHORT((b[y,x + 1][GREEN] + b[y,x - 1][GREEN] + b[y - 1, x][GREEN] + b[y + 1, x][GREEN]) DIV 4));
              a[y,x][BLUE] := SHORT(SHORT((b[y,x + 1][BLUE] + b[y,x - 1][BLUE] + b[y - 1, x][BLUE] + b[y + 1, x][BLUE]) DIV 4));
          END
        END

      END
    END;
    time2 := Kernel.Time();
    fps:=Frames*1000/(time2 - time1);
    Out.String("t="); Out.Real((time2 - time1)/1000);
    Out.String(" fps="); Out.Real(fps);
    Out.Ln;
  END Blur;

END TestBlur.

DevCompiler.CompileThis TestBlur!!
TestBlur.Blur

Прогнал этот вариант на оном референсном ультрабуке (компилировал обычным образом, то есть видимо проверка индексов есть):
BB/CB (trurl):
   time: t= 261
   fps :  3.83
BB/CB (DIV-оптимизация, 2D array - предыдущий вариант):
   time: 303 seconds
   fps : 3.30

Ну, то есть быстрее, но не значительно.

А как отключить проверку индексов?
Название: Re: Blur на разных ЯП.
Отправлено: trurl от Май 07, 2013, 10:50:41 am
Догнал до 7 fps.
MODULE TestBlur2;
  IMPORT Kernel, Out:=StdLog;

  CONST
    W = 640;
    H = 480;
    N = 13;
    Frames = 100;

    RED = 0; GREEN = 1; BLUE = 2;

  TYPE
    Plane = ARRAY H*W, 4 OF BYTE;
   
  VAR 
    a, b : Plane;

  PROCEDURE Blur*;
  VAR
    f, n : INTEGER;
    x, y, z : INTEGER;
    time1, time2 : LONGINT;     
    fps:REAL;
  BEGIN
    time1 := Kernel.Time();

    FOR f:=1 TO Frames DO
      FOR n:=1 TO N DO

        FOR y:= 1 TO H-2 DO
          FOR x:= 1 TO W-2 DO
            z:= y*W+x;
            b[z][RED] := SHORT(SHORT((a[z + 1][RED] + a[z - 1][RED] + a[z - W][RED] + a[z + W][RED]) DIV 4));
            b[z][GREEN] := SHORT(SHORT((a[z + 1][GREEN] + a[z - 1][GREEN] + a[z - W][GREEN] + a[z + W][GREEN]) DIV 4));
            b[z][BLUE] := SHORT(SHORT((a[z + 1][BLUE] + a[z - 1][BLUE] + a[z - W][BLUE] + a[z + W][BLUE]) DIV 4));
          END
        END;

        FOR y:=1 TO H-2 DO
          FOR x:=1 TO W-2 DO
            z:= y*W+x;
            a[z][RED] := SHORT(SHORT((b[z + 1][RED] + b[z - 1][RED] + b[z - W][RED] + b[z + W][RED]) DIV 4));
            a[z][GREEN] := SHORT(SHORT((b[z + 1][GREEN] + b[z - 1][GREEN] + b[z - W][GREEN] + b[z + W][GREEN]) DIV 4));
            a[z][BLUE] := SHORT(SHORT((b[z + 1][BLUE] + b[z - 1][BLUE] + b[z - W][BLUE] + b[z + W][BLUE]) DIV 4));
          END
        END

      END
    END;
    time2 := Kernel.Time();
    fps:=Frames*1000/(time2 - time1);
    Out.String("t="); Out.Real((time2 - time1)/1000);
    Out.String(" fps="); Out.Real(fps);
    Out.Ln;
  END Blur;

END TestBlur2.
Название: Re: Blur на разных ЯП.
Отправлено: trurl от Май 07, 2013, 10:52:43 am

А как отключить проверку индексов?
Там команда для компиляции: (!) DevCompiler.CompileThis TestBlur!!
Название: Re: Blur на разных ЯП.
Отправлено: valexey_u от Май 07, 2013, 11:03:35 am

А как отключить проверку индексов?
Там команда для компиляции: (!) DevCompiler.CompileThis TestBlur!!
Вау! Та же самая версия (не твоя новая 7 fps'ная) собранная вот так, дает такие результаты:
BB/CB (trurl с проверкой индексов):
   time: 261 seconds
   fps :  3.83
BB/CB (trurl без проверки индексов):
   time: 113 seconds
   fps :  8.87
Прирост в 2.5 раза!

Вот она, цена проверки выхода за границы! ;-)
Название: Re: Blur на разных ЯП.
Отправлено: valexey_u от Май 07, 2013, 11:16:16 am
Догнал до 7 fps.
MODULE TestBlur2;
  IMPORT Kernel, Out:=StdLog;

  CONST
    W = 640;
    H = 480;
    N = 13;
    Frames = 100;

    RED = 0; GREEN = 1; BLUE = 2;

  TYPE
    Plane = ARRAY H*W, 4 OF BYTE;
   
  VAR 
    a, b : Plane;

  PROCEDURE Blur*;
  VAR
    f, n : INTEGER;
    x, y, z : INTEGER;
    time1, time2 : LONGINT;     
    fps:REAL;
  BEGIN
    time1 := Kernel.Time();

    FOR f:=1 TO Frames DO
      FOR n:=1 TO N DO

        FOR y:= 1 TO H-2 DO
          FOR x:= 1 TO W-2 DO
            z:= y*W+x;
            b[z][RED] := SHORT(SHORT((a[z + 1][RED] + a[z - 1][RED] + a[z - W][RED] + a[z + W][RED]) DIV 4));
            b[z][GREEN] := SHORT(SHORT((a[z + 1][GREEN] + a[z - 1][GREEN] + a[z - W][GREEN] + a[z + W][GREEN]) DIV 4));
            b[z][BLUE] := SHORT(SHORT((a[z + 1][BLUE] + a[z - 1][BLUE] + a[z - W][BLUE] + a[z + W][BLUE]) DIV 4));
          END
        END;

        FOR y:=1 TO H-2 DO
          FOR x:=1 TO W-2 DO
            z:= y*W+x;
            a[z][RED] := SHORT(SHORT((b[z + 1][RED] + b[z - 1][RED] + b[z - W][RED] + b[z + W][RED]) DIV 4));
            a[z][GREEN] := SHORT(SHORT((b[z + 1][GREEN] + b[z - 1][GREEN] + b[z - W][GREEN] + b[z + W][GREEN]) DIV 4));
            a[z][BLUE] := SHORT(SHORT((b[z + 1][BLUE] + b[z - 1][BLUE] + b[z - W][BLUE] + b[z + W][BLUE]) DIV 4));
          END
        END

      END
    END;
    time2 := Kernel.Time();
    fps:=Frames*1000/(time2 - time1);
    Out.String("t="); Out.Real((time2 - time1)/1000);
    Out.String(" fps="); Out.Real(fps);
    Out.Ln;
  END Blur;

END TestBlur2.

Эта версия, если отключить проверку индексов, выдает такие результаты (для сравнения, рядом результаты C++ версии):
BB/CP (trurl "7 fps" version, range check off):
   time: 88 seconds
   fps : 11.38
C++:
   time: 66
   fps : 15.15
Название: Re: Blur на разных ЯП.
Отправлено: Valery Solovey от Май 07, 2013, 01:47:18 pm
Так а сколько мой вариант на одномерном массиве выдаёт fps? http://oberspace.dyndns.org/index.php/topic,484.msg15894.html#msg15894
Название: Re: Blur на разных ЯП.
Отправлено: trurl от Май 07, 2013, 02:19:56 pm
Прирост в 2.5 раза!
Ух ты! У меня прирост от непроверки далеко не такой.

Еще один страшный вариант.
MODULE TestBlur3;
  IMPORT Kernel,SYSTEM, Out:=StdLog;

  CONST
    W = 640;
    H = 480;
    N = 13;
    Frames = 1000;

  TYPE
Pixel = ARRAY 4 OF BYTE;
    Plane = ARRAY H*W OF Pixel;
   
  VAR 
    a, b : Plane;

  PROCEDURE Blur*;
  VAR
    f, n : INTEGER;
    x, y, z : INTEGER;
q1, q2, q3, q4: SET;
    time1, time2 : LONGINT;     
    fps:REAL;
  CONST
    MaskRB = {0..7,16..23};
  BEGIN
    time1 := Kernel.Time();

    FOR f:=1 TO Frames DO
      FOR n:=1 TO N DO
       z:= W+1;
       FOR y:= 1 TO H-2 DO
         FOR x:= 1 TO W-2 DO
           q1:=SYSTEM.VAL(SET, a[z + 1]);
           q2:=SYSTEM.VAL(SET, a[z - 1]);
           q3:=SYSTEM.VAL(SET, a[z + W]);
           q4:=SYSTEM.VAL(SET, a[z - W]);
           SYSTEM.PUT(SYSTEM.ADR(b[z]),
                BITS( (ORD(q1*MaskRB) + ORD(q2*MaskRB) + ORD(q3*MaskRB) + ORD(q4*MaskRB)) DIV 4)
              + BITS( (ORD(q1-MaskRB) + ORD(q2-MaskRB) + ORD(q3-MaskRB) + ORD(q4-MaskRB)) DIV 4));
           INC(z);
          END;
          INC(z,2);
        END;

        z:= W+1;
        FOR y:=1 TO H-2 DO
          FOR x:=1 TO W-2 DO
           z:= y*W+x;
           q1:=SYSTEM.VAL(SET, b[z + 1]);
           q2:=SYSTEM.VAL(SET, b[z - 1]);
           q3:=SYSTEM.VAL(SET, b[z + W]);
           q4:=SYSTEM.VAL(SET, b[z - W]);
           SYSTEM.PUT(SYSTEM.ADR(a[z]),
                BITS( (ORD(q1*MaskRB) + ORD(q2*MaskRB) + ORD(q3*MaskRB) + ORD(q4*MaskRB)) DIV 4)
              + BITS( (ORD(q1-MaskRB) + ORD(q2-MaskRB) + ORD(q3-MaskRB) + ORD(q4-MaskRB)) DIV 4));
           INC(z);
          END;
          INC(z,2);
        END;
      END
    END;

    time2 := Kernel.Time();
    fps:=Frames*1000/(time2 - time1);
    Out.String("t="); Out.Real((time2 - time1)/1000);
    Out.String(" fps="); Out.Real(fps);
    Out.Ln;
  END Blur;

END TestBlur3.

DevCompiler.CompileThis TestBlur3!!
TestBlur3.Blur
Название: Re: Blur на разных ЯП.
Отправлено: DddIzer от Май 07, 2013, 02:48:29 pm
тык какой результат то ?
Название: Re: Blur на разных ЯП.
Отправлено: valexey_u от Май 07, 2013, 05:40:32 pm
Пока писал версию для двумерного массива, понял, что неправильно соптимизировал версию для одномерного.
Второй заход:
для N=13
одномерный массив - больше 1.5 минуты
двумерный - больше 3 минут

MODULE WorkBlur;
IMPORT Log, Kernel, SYSTEM;

CONST W = 640; H = 480; (* размер кадра в пикселях *)
ln = 1;
clr = 3;
w = (W - 1) * clr; h = H -1; (* размер области кадра на обработке *)
w2 = W * clr;
shift = -2;
F = 1000; (* кол-во кадров *)

PROCEDURE Do*(N : INTEGER);
VAR a1, a2 : POINTER TO ARRAY OF BYTE;
len : INTEGER;
f, n, x, y : INTEGER;
m : INTEGER;
time : LONGINT;
BEGIN
time := Kernel.Time();
len := W * H * clr;
NEW( a1, len );
NEW( a2, len );
f := 0;
WHILE f < F DO

n := 0;
WHILE n < N DO
m := w + 6;

y := 1;
WHILE y < h DO
x := 3;
WHILE x < w DO
a2[m] := SHORT(SHORT(SYSTEM.LSH(a1[m - w2] + a1[m - clr] + a1[m + clr] + a1[m + w2], shift)));
m := m + 1;
x := x + 1
END;
m := m + 6;
y := y + 1
END;

(*<-->*)

m := w + 6;

y := 1;
WHILE y < h DO
x := 3;
WHILE x < w DO
a1[m] := SHORT(SHORT(SYSTEM.LSH(a2[m - w2] + a2[m - clr] + a2[m + clr] + a2[m + w2], shift)));
m := m + 1;
x := x + 1
END;
m := m + 6;
y := y + 1
END;

n := n + 1
END;
f := f + 1
END;
Log.Int(SHORT(Kernel.Time() - time))
END Do;

PROCEDURE Do2*(N : INTEGER);
VAR  a1, a2 : POINTER TO ARRAY OF ARRAY OF BYTE;
len : INTEGER;
f, n, x, y : INTEGER;
time : LONGINT;
BEGIN
time := Kernel.Time();
NEW( a1, H, W * 3 );
NEW( a2, H, W * 3 );
f := 0;

WHILE f < F DO

n := 0;
WHILE n < N DO
y := 1;
WHILE y < h DO
x := 3;
WHILE x < w DO
a2[y, x] := SHORT(SHORT(SYSTEM.LSH(a1[y - ln, x] + a1[y, x - clr] + a1[y, x + clr] + a1[y + ln, x], shift)));
x := x + 1
END;
y := y + 1
END;

y := 1;
WHILE y < h DO
x := 3;
WHILE x < w DO
a1[y, x] := SHORT(SHORT(SYSTEM.LSH(a2[y - ln, x] + a2[y, x - clr] + a2[y, x + clr] + a2[y + ln, x], shift)));
x := x + 1
END;
y := y + 1
END;

n := n + 1
END;
f := f + 1
END;
Log.Int(SHORT(Kernel.Time() - time))
END Do2;

END WorkBlur.

Прогнал.

== With array bound checks ===
BB/CB (Valery Solovey 1D):
   time: 131 seconds
   fps : 7.6
BB/CB (Valery Solovey 2D):
   time: 261 seconds
   fps : 3.8
== Without array bound checks ===
BB/CB (Valery Solovey 1D):
   time: 103 seconds
   fps : 9.7 fps
BB/CB (Valery Solovey 2D):
   time: 158 seconds
   fps : 6.3
Название: Re: Blur на разных ЯП.
Отправлено: valexey_u от Май 07, 2013, 05:50:55 pm
Прирост в 2.5 раза!
Ух ты! У меня прирост от непроверки далеко не такой.
А процессор какой? У меня мобильный i5. Подозреваю что у разных процессоров алгоритм предсказания немного разный. А ветвления (любые) сильно мешают алгоритму предсказания и увеличивают промахи кеша.

Еще один страшный вариант.
MODULE TestBlur3;
  IMPORT Kernel,SYSTEM, Out:=StdLog;

  CONST
    W = 640;
    H = 480;
    N = 13;
    Frames = 1000;

  TYPE
Pixel = ARRAY 4 OF BYTE;
    Plane = ARRAY H*W OF Pixel;
   
  VAR 
    a, b : Plane;

  PROCEDURE Blur*;
  VAR
    f, n : INTEGER;
    x, y, z : INTEGER;
q1, q2, q3, q4: SET;
    time1, time2 : LONGINT;     
    fps:REAL;
  CONST
    MaskRB = {0..7,16..23};
  BEGIN
    time1 := Kernel.Time();

    FOR f:=1 TO Frames DO
      FOR n:=1 TO N DO
       z:= W+1;
       FOR y:= 1 TO H-2 DO
         FOR x:= 1 TO W-2 DO
           q1:=SYSTEM.VAL(SET, a[z + 1]);
           q2:=SYSTEM.VAL(SET, a[z - 1]);
           q3:=SYSTEM.VAL(SET, a[z + W]);
           q4:=SYSTEM.VAL(SET, a[z - W]);
           SYSTEM.PUT(SYSTEM.ADR(b[z]),
                BITS( (ORD(q1*MaskRB) + ORD(q2*MaskRB) + ORD(q3*MaskRB) + ORD(q4*MaskRB)) DIV 4)
              + BITS( (ORD(q1-MaskRB) + ORD(q2-MaskRB) + ORD(q3-MaskRB) + ORD(q4-MaskRB)) DIV 4));
           INC(z);
          END;
          INC(z,2);
        END;

        z:= W+1;
        FOR y:=1 TO H-2 DO
          FOR x:=1 TO W-2 DO
           z:= y*W+x;
           q1:=SYSTEM.VAL(SET, b[z + 1]);
           q2:=SYSTEM.VAL(SET, b[z - 1]);
           q3:=SYSTEM.VAL(SET, b[z + W]);
           q4:=SYSTEM.VAL(SET, b[z - W]);
           SYSTEM.PUT(SYSTEM.ADR(a[z]),
                BITS( (ORD(q1*MaskRB) + ORD(q2*MaskRB) + ORD(q3*MaskRB) + ORD(q4*MaskRB)) DIV 4)
              + BITS( (ORD(q1-MaskRB) + ORD(q2-MaskRB) + ORD(q3-MaskRB) + ORD(q4-MaskRB)) DIV 4));
           INC(z);
          END;
          INC(z,2);
        END;
      END
    END;

    time2 := Kernel.Time();
    fps:=Frames*1000/(time2 - time1);
    Out.String("t="); Out.Real((time2 - time1)/1000);
    Out.String(" fps="); Out.Real(fps);
    Out.Ln;
  END Blur;

END TestBlur3.

DevCompiler.CompileThis TestBlur3!!
TestBlur3.Blur

Результаты прогонов страшного варианта:
BB/CB (trurl/SYSTEM with array bound checks)
   time: 81 seconds
   fps : 12.2
BB/CB (trurl/SYSTEM without array bound checks)
   time: 77 seconds
   fps : 13.0
Название: Re: Blur на разных ЯП.
Отправлено: valexey_u от Май 07, 2013, 08:10:11 pm
Кстати, о корректности: в исходных данных картинки мы имеем набор unsigned char'ов, то есть беззнаковых целых в диапазоне от 0 до 255. Насколько я понимаю, в КП у нас таки тип BYTE знаковый, соответственно нужно как-то конвертировать наверное...

Вообще, как корректно биндинг строится к функции вида:
bool __stdcall PXCUPipeline_QueryRGB(PXCUPipeline_Instance instance, unsigned char *data);

?
Название: Re: Blur на разных ЯП.
Отправлено: valexey_u от Май 07, 2013, 08:45:38 pm
Кстати, о корректности: в исходных данных картинки мы имеем набор unsigned char'ов, то есть беззнаковых целых в диапазоне от 0 до 255. Насколько я понимаю, в КП у нас таки тип BYTE знаковый, соответственно нужно как-то конвертировать наверное...

Вообще, как корректно биндинг строится к функции вида:
bool __stdcall PXCUPipeline_QueryRGB(PXCUPipeline_Instance instance, unsigned char *data);

?
Если посмотреть на жабу, то там unsigned char отображают тупо в int. То есть был массив байт, стал массив 4байтных целых. Причем так, что один пиксель == одно целое 4 байтное число, RGBA.

Ну и соответственно, чтобы как-то с этим жить, там есть замечательные функции вида:
Цитировать
public final float green(int rgb)

Extracts the green value from a color, scaled to match current colorMode(). This value is always returned as a float so be careful not to assign it to an int value.

The green() function is easy to use and undestand, but is slower than another technique. To achieve the same results when working in colorMode(RGB, 255), but with greater speed, use the >> (right shift) operator with a bit mask. For example, the following two lines of code are equivalent:
float r1 = green(myColor);
float r2 =
 myColor >> 8 & 0xFF;

Parameters:
rgb - any value of the color datatype

Ну и конечно функция для создания данных для одного пикселя:
public final int color(int v1,
        int v2,
        int v3,
        int a)
Название: Re: Blur на разных ЯП.
Отправлено: ilovb от Май 08, 2013, 06:28:09 am
Мне кажется что не нужно конвертить. Должно так работать.
Название: Re: Blur на разных ЯП.
Отправлено: trurl от Май 08, 2013, 06:34:24 am
Кстати, о корректности: в исходных данных картинки мы имеем набор unsigned char'ов, то есть беззнаковых целых в диапазоне от 0 до 255. Насколько я понимаю, в КП у нас таки тип BYTE знаковый, соответственно нужно как-то конвертировать наверное...
Да, надо. Либо MOD 256 добавлять, либо вместо BYTE использовать SHORTCHAR.
Название: Re: Blur на разных ЯП.
Отправлено: vlad от Май 11, 2013, 07:31:29 pm
Oberon-07/11

Теперь этот вариант можно скомпилить и запустить прямо в браузере - см. шапку форума ;) Компилятор сырой, но подрихтованный вариант akron1 он компилит (я закомментировал импорты)
MODULE Blur;

  (*IMPORT dt := DateTime, In, Out, RTL;*)

  CONST
    W = 640; W1 = 640 - 3;
    H = 480; H1 = 480 - 3;
    N = 13;
    Frames = 1;

  TYPE
    Plane = ARRAY W*3, H OF CHAR;

  VAR
    a, b:  Plane;
    time: LONGREAL;

  PROCEDURE Blur2DArray*;
  VAR
    f, n : INTEGER;
    x, y : INTEGER;
    color : INTEGER;
  BEGIN
    FOR f:=1 TO Frames DO
      FOR n:=1 TO N DO
        FOR y:=1 TO H-2 DO
          FOR x:=1 TO W-2 DO
            FOR color:=0 TO 2 DO
              b[x*3+color,y] := CHR((ORD(a[x*3+color,y+1])+ORD(a[x*3+color,y-1])+ORD(a[(x-1)*3,y])+ORD(a[(x+1)*3,y])) DIV 4);
            END
          END
        END;
        FOR y:=1 TO H-2 DO
          FOR x:=1 TO W-2 DO
            FOR color:=0 TO 2 DO
              a[x*3+color,y] := CHR((ORD(b[x*3+color,y+1])+ORD(b[x*3+color,y-1])+ORD(b[(x-1)*3,y])+ORD(b[(x+1)*3,y])) DIV 4);
            END
          END
        END
      END
    END;
  END Blur2DArray;

BEGIN
  (*In.Open;
  Out.Open;
  time := dt.Now();*)
  Blur2DArray;
  (*Out.FixReal(LONG(FLT(Frames))/((dt.Now() - time) * 86400.D0), 20, 5);
  In.Ln;*)
END Blur.
Название: Re: Blur на разных ЯП.
Отправлено: valexey_u от Май 11, 2013, 07:36:03 pm
Oberon-07/11

Теперь этот вариант можно скомпилить и запустить прямо в браузере - см. шапку форума ;) Компилятор сырой, но подрихтованный вариант akron1 он компилит (я закомментировал импорты)
MODULE Blur;

  (*IMPORT dt := DateTime, In, Out, RTL;*)

  CONST
    W = 640; W1 = 640 - 3;
    H = 480; H1 = 480 - 3;
    N = 13;
    Frames = 1;

  TYPE
    Plane = ARRAY W*3, H OF CHAR;

  VAR
    a, b:  Plane;
    time: LONGREAL;

  PROCEDURE Blur2DArray*;
  VAR
    f, n : INTEGER;
    x, y : INTEGER;
    color : INTEGER;
  BEGIN
    FOR f:=1 TO Frames DO
      FOR n:=1 TO N DO
        FOR y:=1 TO H-2 DO
          FOR x:=1 TO W-2 DO
            FOR color:=0 TO 2 DO
              b[x*3+color,y] := CHR((ORD(a[x*3+color,y+1])+ORD(a[x*3+color,y-1])+ORD(a[(x-1)*3,y])+ORD(a[(x+1)*3,y])) DIV 4);
            END
          END
        END;
        FOR y:=1 TO H-2 DO
          FOR x:=1 TO W-2 DO
            FOR color:=0 TO 2 DO
              a[x*3+color,y] := CHR((ORD(b[x*3+color,y+1])+ORD(b[x*3+color,y-1])+ORD(b[(x-1)*3,y])+ORD(b[(x+1)*3,y])) DIV 4);
            END
          END
        END
      END
    END;
  END Blur2DArray;

BEGIN
  (*In.Open;
  Out.Open;
  time := dt.Now();*)
  Blur2DArray;
  (*Out.FixReal(LONG(FLT(Frames))/((dt.Now() - time) * 86400.D0), 20, 5);
  In.Ln;*)
END Blur.

Нюанс - в этом исходнике обрабатывается ОДИН кадр (Frames = 1). Так что не удивляйтесь быстрому завершению работы алгоритма. :-)
Название: Re: Blur на разных ЯП.
Отправлено: akron1 от Май 11, 2013, 08:00:28 pm
Обнаружил ошибку в сравнении целых

MODULE test;
IMPORT JS;
VAR x: INTEGER;
BEGIN
    x := 10;
    IF x >= 0 THEN
      JS.alert("TRUE")
    ELSE
      JS.alert("FALSE")
    END
END test.

строка
IF x >= 0 THEN

транслируется так
if (RTL$.setInclR(x, 0))

и естественно не работает как надо, похоже, что компилятор применяет операцию ">=" перегруженную для множеств.
Операции ">" и "<" для целых не работают вообще, пишет: TypeError: Cannot call method 'replace' of undefined.
Кстати операции ">=" и "<=" для множеств тоже работают неправильно:
MODULE test;
IMPORT JS;
VAR s1, s2: SET;
BEGIN
    s1 := {0..5};
    s2 := {0..8};
    IF s1 <= s2 THEN
      JS.alert("TRUE")
    ELSE
      JS.alert("FALSE")
    END
END test.
Программа пишет "FALSE" (должно быть "TRUE")
Название: Re: Blur на разных ЯП.
Отправлено: vlad от Май 11, 2013, 08:25:52 pm
Обнаружил ошибку в сравнении целых

Спасибо! Буду фиксить :)
Название: Re: Blur на разных ЯП.
Отправлено: valexey_u от Май 14, 2013, 05:20:06 pm
Начал проверку на корректность алгоритмов. Пока проверил код генерируемый компилятором vlad'a - он выдает корректный результат (то есть это Oberon-07/11). И проверил js-реализацию.

Планирую как минимум проверить следующие реализации: C#, C++, CB/BB (несколько), Oberon-07 (две под винду), возможно Lua-jit.

Oberon-2, F#, Ada, Delphi, Java, Fortran скорее всего окажутся пока за бортом - у меня просто на них времени и сил не хватит.
Название: Re: Blur на разных ЯП.
Отправлено: valexey_u от Май 25, 2013, 01:36:17 am
GPCP for .NET. Наивная реализация алгоритма. Ключи компиляции: /nodebug /nocheck (/nocheck убирает проверку целочисленного переполнение - это дает выигрыш в два раза, суммарно эти две опции дают выигрыш примерно в 10 раз).

Время работы: 171 секунда.
Для сравнения, примерно то же самое в ББ работает порядка 560 секунд.

Наивная реализация:
MODULE Blur;
    IMPORT CPmain;
   
    CONST
        width = 640;
        height = 480;
        N = 13;
        frames = 1000;
       
        red = 0;
        green = 1;
        blue = 2;
       
    TYPE
        Frame = ARRAY width*height*(blue+1) OF SHORTCHAR;
           
    PROCEDURE Index(x,y,color : INTEGER) : INTEGER;
    BEGIN
        RETURN ((x+y*width)*3+color)
    END Index;
   
    PROCEDURE Blur(IN in : Frame; OUT out : Frame);
    VAR
        x,y,c : INTEGER;
    BEGIN
        FOR y:=1 TO height-2 DO
            FOR x:=1 TO width-2 DO
                FOR c:=red TO blue DO
                    out[Index(x,y,c)] := SHORT(CHR( ( ORD(in[Index(x,y-1,c)]) + ORD(in[Index(x,y+1,c)]) +
                                                            ORD(in[Index(x-1,y,c)]) + ORD(in[Index(x+1,y,c)]) ) DIV 4  ));
                END;
            END;
        END;
    END Blur;
   
    PROCEDURE Do*;
    VAR
        time : LONGINT;
        f, n : INTEGER;
        a1, a2 : POINTER TO Frame;
    BEGIN
        NEW(a1);
        NEW(a2);
       
        FOR f:=1 TO frames DO
            FOR n:=1 TO N DO               
                Blur(a1,a2);
                Blur(a2,a1)
            END
        END;
    END Do;
BEGIN
    Do;
END Blur.
Название: Re: Blur на разных ЯП.
Отправлено: valexey_u от Май 25, 2013, 03:00:12 am
В компиляторе vlad'а не реализованы встроенные процедуры-функции вроде ROR, ASR и так далее. Зарепортил: https://github.com/vladfolts/oberonjs/issues/4
Название: Re: Blur на разных ЯП.
Отправлено: valexey_u от Май 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 и отключением проверки границ массивов.