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

valexey_u

  • Hero Member
  • *****
  • Сообщений: 3013
    • Просмотр профиля
Re: Blur на разных ЯП.
« Ответ #15 : Апрель 24, 2013, 07:24:05 pm »
Значит оптимизации тут роли особой не играют. Скорее всего поможет только отключение проверок.
Возможно имеет смысл вычислять эти оффсеты один раз для всех 4 пикселов. Что-то вроде того, как Валерий предлагал. Надо будет попробовать.
Y = λf.(λx.f (x x)) (λx.f (x x))

DddIzer

  • Гость
Re: Blur на разных ЯП.
« Ответ #16 : Апрель 24, 2013, 08:28:36 pm »
Значит оптимизации тут роли особой не играют. Скорее всего поможет только отключение проверок.
Возможно имеет смысл вычислять эти оффсеты один раз для всех 4 пикселов. Что-то вроде того, как Валерий предлагал. Надо будет попробовать.
может лучше мозги не трахать а попробовать вот это http://web.archive.org/web/20060718054020/http://www.acm.uiuc.edu/siggraph/workshops/wjarosz_convolution_2001.pdf  ;)

valexey_u

  • Hero Member
  • *****
  • Сообщений: 3013
    • Просмотр профиля
Re: Blur на разных ЯП.
« Ответ #17 : Апрель 24, 2013, 09:15:25 pm »
Значит оптимизации тут роли особой не играют. Скорее всего поможет только отключение проверок.
Возможно имеет смысл вычислять эти оффсеты один раз для всех 4 пикселов. Что-то вроде того, как Валерий предлагал. Надо будет попробовать.
может лучше мозги не трахать а попробовать вот это http://web.archive.org/web/20060718054020/http://www.acm.uiuc.edu/siggraph/workshops/wjarosz_convolution_2001.pdf  ;)
Спасибо за ссылку конечно, но это офтопик. В данной теме (перечитай первое сообщение) мы сравниваем скорость разных ЯП на одном и том же алгоритме. Это бенчмарк по сути.

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

Впрочем под это не грех будет и отдельный топик завести.
Y = λf.(λx.f (x x)) (λx.f (x x))

DddIzer

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

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

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

valexey_u

  • Hero Member
  • *****
  • Сообщений: 3013
    • Просмотр профиля
Re: Blur на разных ЯП.
« Ответ #19 : Апрель 24, 2013, 09:20:13 pm »
Спасибо за ссылку конечно, но это офтопик. В данной теме (перечитай первое сообщение) мы сравниваем скорость разных ЯП на одном и том же алгоритме. Это бенчмарк по сути.

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

Впрочем под это не грех будет и отдельный топик завести.
  ;) Да ну... это было бы оффтопиком если бы не большинство сообщений об усовершенствованиях - в том числе и ваше (на которое я ответил)...
Эти усовершенствования алгоритм не меняли, если угодно, это были всего лишь подсказки компилятору.
Y = λf.(λx.f (x x)) (λx.f (x x))

DddIzer

  • Гость
Re: Blur на разных ЯП.
« Ответ #20 : Апрель 24, 2013, 09:20:49 pm »
 я к чему это... бенчмарктесь на здоровье но на качественной основе...

valexey_u

  • Hero Member
  • *****
  • Сообщений: 3013
    • Просмотр профиля
Re: Blur на разных ЯП.
« Ответ #21 : Апрель 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));
Y = λf.(λx.f (x x)) (λx.f (x x))

Губанов Сергей Юрьевич

  • Hero Member
  • *****
  • Сообщений: 590
    • Просмотр профиля
    • Домашняя страница
Re: Blur на разных ЯП.
« Ответ #22 : Апрель 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);
}
}
}
}

Прилагаю картинки (в архиве)

Geniepro

  • Hero Member
  • *****
  • Сообщений: 1955
  • Знайте- истина в том, что повторено трижды подряд!
    • Просмотр профиля
Re: Blur на разных ЯП.
« Ответ #23 : Апрель 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;
}
to iterate is human, to recurse, divine

Салат «рекурсия»: помидоры, огурцы, салат…

valexey_u

  • Hero Member
  • *****
  • Сообщений: 3013
    • Просмотр профиля
Re: Blur на разных ЯП.
« Ответ #24 : Апрель 25, 2013, 12:56:39 pm »
Сделал цвета однобайтовыми, делаю блюр в трёх каналах, загружаю из картинки.
Предлагаю продолжить обсуждение алгоритмов тут: Сравнение blur-алгоритмов.
Y = λf.(λx.f (x x)) (λx.f (x x))

valexey_u

  • Hero Member
  • *****
  • Сообщений: 3013
    • Просмотр профиля
Re: Blur на разных ЯП.
« Ответ #25 : Апрель 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?
А за реализацию на Аде - отдельное спасибо. Буду тестировать :-)
Y = λf.(λx.f (x x)) (λx.f (x x))

Geniepro

  • Hero Member
  • *****
  • Сообщений: 1955
  • Знайте- истина в том, что повторено трижды подряд!
    • Просмотр профиля
Re: Blur на разных ЯП.
« Ответ #26 : Апрель 25, 2013, 01:09:30 pm »
Интересно TinyC умеет inline?
Похоже, что не умеет, потому что когда я вынес алгоритм самого блура в процедуру Blur, время работы выросло почти на 5%...

А за реализацию на Аде - отдельное спасибо. Буду тестировать :-)
Пока делал вариант на Аде -- половину времени потратил на то, что бы вывести результат в stdio -- с выводом чисел и всяких пользовательских там беда...
to iterate is human, to recurse, divine

Салат «рекурсия»: помидоры, огурцы, салат…

valexey_u

  • Hero Member
  • *****
  • Сообщений: 3013
    • Просмотр профиля
Re: Blur на разных ЯП.
« Ответ #27 : Апрель 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 секунды от теста к тесту.
Y = λf.(λx.f (x x)) (λx.f (x x))

akron1

  • Jr. Member
  • **
  • Сообщений: 76
    • Просмотр профиля
Re: Blur на разных ЯП.
« Ответ #28 : Апрель 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


valexey_u

  • Hero Member
  • *****
  • Сообщений: 3013
    • Просмотр профиля
Re: Blur на разных ЯП.
« Ответ #29 : Апрель 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?
Ну и делфи, до кучи.
Y = λf.(λx.f (x x)) (λx.f (x x))