OberonCore

Библиотека  Wiki  Форум  BlackBox  Компоненты  Проекты
Текущее время: Пятница, 29 Март, 2024 01:53

Часовой пояс: UTC + 3 часа




Начать новую тему Ответить на тему  [ Сообщений: 41 ]  На страницу 1, 2, 3  След.
Автор Сообщение
 Заголовок сообщения: Виртуальная машина на CP
СообщениеДобавлено: Вторник, 21 Май, 2019 21:13 

Зарегистрирован: Вторник, 30 Июнь, 2009 14:58
Сообщения: 1549
Задумал я тут ВМ написать (под скриптовый DSL для определенных нужд)

Идея простая как бревно. Есть универсальный интерфейс Value для любых значений.
Значениями могут быть числа с плавающей точкой, строки, объекты etc. (в примере только числа)
Машина предполагается регистровая. Каждая инструкция 4 байта.
Я написал простой тестовый пример. Надеюсь по коду понятно что происходит.

Это я руками сделал тупую компиляцию следующего:
Код:
x = 0
y = 1
while x <= 100000000 do
   x = x + y
end


Как улучшить следующий подход?
Можно ли избежать лишней работы с кучей не прибегая к union?

Больше всего меня интересует скорость исполнения байткода. Этот пример у меня выполняется 6 сек., что слишком долго.

ps Просьба не обращать внимание на стиль, т.к. написано левой пяткой только ради эксперимента.

Код:
MODULE MyTest;
IMPORT Log := StdLog;

CONST
   Add = 0; Set = 1; Get = 2; Jmp = 3; Jgt = 4; End = 5;

TYPE

Value = POINTER TO EXTENSIBLE RECORD END;

Number = POINTER TO RECORD(Value)
   r: REAL;
END;

PROCEDURE (v: Value) Num(): REAL, NEW, EXTENSIBLE;
BEGIN
RETURN 0;
END Num;

PROCEDURE (v: Value) SetReal(x: REAL), NEW, EXTENSIBLE;
BEGIN
END SetReal;

PROCEDURE (v: Value) Set(x: Value), NEW, EXTENSIBLE;
BEGIN
END Set;

PROCEDURE (v: Number) Num(): REAL;
BEGIN
RETURN v.r;
END Num;

PROCEDURE (v: Number) SetReal(x: REAL);
BEGIN
   v.r := x;
END SetReal;

PROCEDURE (v: Number) Set(x: Value);
BEGIN
   v.r := x.Num();
END Set;

PROCEDURE emit1(b1, b2, b3, b4: INTEGER): INTEGER;
   VAR w: INTEGER;
BEGIN
   w := ASH(b1, 24) + ASH(b2, 16) + ASH(b3, 8) + b4;
   RETURN w;
END emit1;

PROCEDURE emit2(b1, b2, b4: INTEGER): INTEGER;
   VAR w: INTEGER;
BEGIN
   w := ASH(b1, 24) + ASH(b2, 16) + b4;
   RETURN w;
END emit2;

PROCEDURE emit3(b1, b4: INTEGER): INTEGER;
   VAR w: INTEGER;
BEGIN
   w := ASH(b1, 24) + b4;
   RETURN w;
END emit3;

PROCEDURE emit4(b1: INTEGER): INTEGER;
   VAR w: INTEGER;
BEGIN
   w := ASH(b1, 24);
   RETURN w;
END emit4;

PROCEDURE Do*;
   VAR w: INTEGER;
   b1, b2, b3, b4: INTEGER;
   ip: INTEGER;
   ops: ARRAY 13 OF INTEGER;
   reg: ARRAY 256 OF Value;
   mem: ARRAY 1000 OF Value;
   r: REAL;
   n: Number;
   i: INTEGER;
BEGIN
   
   (* помещение программы в память кода *)

   ops[00] := emit2(Get, 0, 0);    (* 0 *)
   ops[01] := emit2(Set, 0, 10);   (* x = 0 *)
   ops[02] := emit2(Get, 0, 1);    (* 1 *)
   ops[03] := emit2(Set, 0, 11);   (* y = 1 *)
   ops[04] := emit2(Get, 0, 10);   (* x *)
   ops[05] := emit2(Get, 1, 2);    (* 100000000 *)
   ops[06] := emit3(Jgt, 11);      (* if x > 100000000 goto *)
   ops[07] := emit2(Get, 0, 10);   (* x *)
   ops[08] := emit2(Get, 1, 11);   (* y *)
   ops[09] := emit1(Add, 0, 0, 1); (* _ = x + y *)
   ops[10] := emit2(Set, 0, 10);   (* x = _ *)
   ops[11] := emit3(Jmp, 3);       (* goto *)
   ops[12] := emit4(End);          (* end *)
   
   (* подготовка регистров *)
   
   FOR i := 0 TO LEN(reg) - 1 DO
      NEW(n); n.r := 0;
      reg[i] := n;
   END;
   
   (* подготовка памяти данных *)
   
   FOR i := 0 TO 20 DO
      NEW(n); n.r := 0;
      mem[i] := n;
   END;
   
   (* размещение констант в памяти *)

   NEW(n); n.r := 0;
   mem[0] := n;
   
   NEW(n); n.r := 1;
   mem[1] := n;
   
   NEW(n); n.r := 100000000;
   mem[2] := n;
   
   (* цикл ВМ *)

   ip := 0;
   
   i := 0;
   LOOP
      w := ops[ip];
      
      b4 := w MOD 0100H;
      b3 := w DIV 0100H MOD 0100H;
      b2 := w DIV 010000H MOD 0100H;
      b1 := w DIV 01000000H MOD 0100H;
         
      CASE b1 OF
      |Get: reg[b2].Set(mem[b4]);
      |Set: mem[b4].Set(reg[b2]);
      |Add: reg[b2].SetReal(reg[b3].Num() + reg[b4].Num());
      |Jmp: ip := b4;
      |Jgt: IF reg[0].Num() > reg[1].Num() THEN ip := b4 END;
      |End: EXIT;
      END;
      INC(ip);
      
   END;
   
END Do;

END MyTest.Do

DevCompiler.CompileThis MyTest!!
DevDebug.UnloadThis MyTest


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Виртуальная машина на CP
СообщениеДобавлено: Вторник, 21 Май, 2019 21:40 

Зарегистрирован: Вторник, 30 Июнь, 2009 14:58
Сообщения: 1549
Вот еще до кучи накидал вариант с union:

Код:
MODULE MyTest;
IMPORT Log := StdLog, SYSTEM;

CONST
   Add = 0; Set = 1; Get = 2; Jmp = 3; Jgt = 4; End = 5;

TYPE

   Value = RECORD
      type: INTEGER;
      data: RECORD [union]
         r: REAL;
         s: POINTER [untagged] TO ARRAY OF CHAR;
      END;
   END;

PROCEDURE emit1(b1, b2, b3, b4: INTEGER): INTEGER;
   VAR w: INTEGER;
BEGIN
   w := ASH(b1, 24) + ASH(b2, 16) + ASH(b3, 8) + b4;
   RETURN w;
END emit1;

PROCEDURE emit2(b1, b2, b4: INTEGER): INTEGER;
   VAR w: INTEGER;
BEGIN
   w := ASH(b1, 24) + ASH(b2, 16) + b4;
   RETURN w;
END emit2;

PROCEDURE emit3(b1, b4: INTEGER): INTEGER;
   VAR w: INTEGER;
BEGIN
   w := ASH(b1, 24) + b4;
   RETURN w;
END emit3;

PROCEDURE emit4(b1: INTEGER): INTEGER;
   VAR w: INTEGER;
BEGIN
   w := ASH(b1, 24);
   RETURN w;
END emit4;

PROCEDURE Do*;
   VAR w: INTEGER;
   b1, b2, b3, b4: INTEGER;
   ip: INTEGER;
   ops: ARRAY 13 OF INTEGER;
   reg: POINTER TO ARRAY 256 OF Value;
   mem: POINTER TO ARRAY 1000 OF Value;
BEGIN
   
   ops[00] := emit2(Get, 0, 0);    (* 0 *)
   ops[01] := emit2(Set, 0, 10);   (* x = 0 *)
   ops[02] := emit2(Get, 0, 1);    (* 1 *)
   ops[03] := emit2(Set, 0, 11);   (* y = 1 *)
   ops[04] := emit2(Get, 0, 10);   (* x *)
   ops[05] := emit2(Get, 1, 2);    (* 100000000 *)
   ops[06] := emit3(Jgt, 11);      (* if x > 100000000 goto *)
   ops[07] := emit2(Get, 0, 10);   (* x *)
   ops[08] := emit2(Get, 1, 11);   (* y *)
   ops[09] := emit1(Add, 0, 0, 1); (* _ = x + y *)
   ops[10] := emit2(Set, 0, 10);   (* x = _ *)
   ops[11] := emit3(Jmp, 3);       (* goto *)
   ops[12] := emit4(End);          (* end *)
   
   NEW(reg);
   NEW(mem);
   
   mem[0].data.r := 0;
   mem[1].data.r := 1;
   mem[2].data.r := 100000000;
   
   ip := 0;
   LOOP
      w := ops[ip];
      
      b4 := w MOD 0100H;
      b3 := w DIV 0100H MOD 0100H;
      b2 := w DIV 010000H MOD 0100H;
      b1 := w DIV 01000000H MOD 0100H;
         
      CASE b1 OF
      |Get: reg[b2] := mem[b4];
      |Set: mem[b4] := reg[b2];
      |Add: reg[b2].data.r := reg[b3].data.r + reg[b4].data.r;
      |Jmp: ip := b4;
      |Jgt: IF reg[0].data.r > reg[1].data.r THEN ip := b4 END;
      |End: EXIT;
      END;
      INC(ip);
      
   END;
   
END Do;

END MyTest.Do

DevCompiler.CompileThis MyTest!!
DevDebug.UnloadThis MyTest


Вроде кажется что это должно быть существенно быстрее... но нет. Чуда не произошло. Этот код выполняется чуть меньше 4 сек (всего на 2 сек. быстрее)
Что я делаю не так? Я хочу добиться как минимум 2 секунд, т.к. на C аналогичный код (O1) выполняется менее 1.8 сек, а на Go на интерфейсах! 2.5 сек.


Последний раз редактировалось ilovb Вторник, 21 Май, 2019 22:51, всего редактировалось 1 раз.

Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Виртуальная машина на CP
СообщениеДобавлено: Вторник, 21 Май, 2019 22:13 

Зарегистрирован: Четверг, 08 Май, 2008 19:13
Сообщения: 1447
Откуда: Киев
Разве в других случаях Blackbox отстаёт не в те же 3-4 раза?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Виртуальная машина на CP
СообщениеДобавлено: Вторник, 21 Май, 2019 22:21 

Зарегистрирован: Вторник, 30 Июнь, 2009 14:58
Сообщения: 1549
Ну обычно мне примерно понятно почему отстает. А сейчас вообще нет идей что за магия может быть в оптимизаторах C и Go, которая позволяет им в данном случае быть как минимум в 2 раза быстрее. Ну и кроме того мы наверно можем руками подобные оптимизации сделать, нет?

Кстати я только что смог сократить до 3 сек. заменив это:

Код:
|Get: reg[b2] := mem[b4];
|Set: mem[b4] := reg[b2];


на это:
Код:
|Get: reg[b2].type := mem[b4].type; reg[b2].data.r := mem[b4].data.r;
|Set: mem[b4].type := reg[b2].type; mem[b4].data.r := reg[b2].data.r;


Что-то не врубаюсь почему это быстрее. :|

ps Люди, а как размещать untagged? Я не могу с union безопасные указатели использовать?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Виртуальная машина на CP
СообщениеДобавлено: Вторник, 21 Май, 2019 23:18 

Зарегистрирован: Понедельник, 28 Ноябрь, 2005 10:28
Сообщения: 1428
Comdiv писал(а):
Разве в других случаях Blackbox отстаёт не в те же 3-4 раза?

Обычно раза в 2 от си и на одном уровне с го.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Виртуальная машина на CP
СообщениеДобавлено: Среда, 22 Май, 2019 00:38 

Зарегистрирован: Вторник, 30 Июнь, 2009 14:58
Сообщения: 1549
Ну нее. В 2 раза медленнее Go - куда ближе к правде.

Все таки я сейчас замеры в BB делаю при отключенных проверках.

А вот кстати с высокоуровневым кодом на C# примерно похоже (4.5 сек против 6 сек. в BB):

Код:
using System;

namespace core_hello
{
    class Program
    {
        public static class OPER {
            public const int ADD = 0;
            public const int SET = 1;
            public const int GET = 2;
            public const int JMP = 3;
            public const int JGT = 4;
            public const int END = 5;
        };
       
        public interface Value
        {
            void Set(Value v);
            void SetReal(double r);
            double Num();

        }

        class Number: Value
        {
            double n;
            public void Set(Value v) {
                n = v.Num();
            }
            public void SetReal(double r) {
                n = r;
            }
            public double Num() {
                return n;
            }

            public Number(double x) {
                n = x;
            }
        }

        static int emit1(byte b1, byte b2, byte b3, byte b4) {
            return (b1<<24) + (b2<<16) + (b3<<8) + b4;
        }

        static int emit2(byte b1, byte b2, byte b4) {
            return (b1<<24) + (b2<<16) + b4;
        }

        static int emit3(byte b1, byte b4) {
            return (b1<<24) + b4;
        }

        static int emit4(byte b1) {
            return b1<<24;
        }

        static void Main(string[] args)
        {

            int[] ops = new int[13];
   
            ops[0] = emit2(OPER.GET, 0, 0);    // 0
            ops[1] = emit2(OPER.SET, 0, 10);   // x = 0
            ops[2] = emit2(OPER.GET, 0, 1);    // 1
            ops[3] = emit2(OPER.SET, 0, 11);   // y = 1
            ops[4] = emit2(OPER.GET, 0, 10);   // x
            ops[5] = emit2(OPER.GET, 1, 2);    // 100000000
            ops[6] = emit3(OPER.JGT, 11);      // if x > 100000000 goto
            ops[7] = emit2(OPER.GET, 0, 10);   // x
            ops[8] = emit2(OPER.GET, 1, 11);   // y
            ops[9] = emit1(OPER.ADD, 0, 0, 1); // _ = x + y
            ops[10] = emit2(OPER.SET, 0, 10);   // x = _
            ops[11] = emit3(OPER.JMP, 3);       // goto
            ops[12] = emit4(OPER.END);          // end

            Value[] reg = new Value[256];
            Value[] mem = new Value[1000];

            for(int i = 0; i < reg.Length; i++) {
                reg[i] = new Number(0);
            }

            for(int i = 0; i < mem.Length; i++) {
                mem[i] = new Number(0);
            }

            mem[0] = new Number(0);
            mem[1] = new Number(1);
            mem[2] = new Number(100000000);

            int ip = 0;

            for (;;) {
                int w = ops[ip];

                int b4 = w & 0xFF;
                int b3 = (w >> 8) & 0xFF;
                int b2 = (w >> 16) & 0xFF;
                int b1 = (w >> 24) & 0xFF;

                switch (b1) {
                case OPER.GET:
                    reg[b2].Set(mem[b4]); break;
                case OPER.SET:
                    mem[b4].Set(reg[b2]); break;
                case OPER.ADD:
                    reg[b2].SetReal(reg[b3].Num() + reg[b4].Num()); break;
                case OPER.JMP:
                    ip = b4; break;
                case OPER.JGT:
                    if (reg[0].Num() > reg[1].Num()) {
                        ip = b4;
                    }
                    break;
                case OPER.END:
                    goto endloop;
                }
                ip++;

            }

            endloop:
           
            Console.WriteLine(mem[10].Num());

        }
    }
}


Правда я c# готовить не умею. Впрочем видимо как и BB.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Виртуальная машина на CP
СообщениеДобавлено: Среда, 22 Май, 2019 00:42 
Аватара пользователя

Зарегистрирован: Воскресенье, 09 Декабрь, 2018 15:14
Сообщения: 113
Откуда: Equestria
Вооружайся дизассемблером.

> Что-то не врубаюсь почему это быстрее. :|
Значит на современных процессорах mov быстрее чем movsd. На 486 может быть было быстрее.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Виртуальная машина на CP
СообщениеДобавлено: Среда, 22 Май, 2019 02:28 

Зарегистрирован: Вторник, 30 Июнь, 2009 14:58
Сообщения: 1549
Java всех порвала в клочья. Высокоуровневый код (аналогично C# и первому варианту BB) выполняется 1.6 сек (практически вровень с сишным низкоуровневым кодом с оптимизацией O3)

Код:
class HelloWorld {
   
    public static class OPER {
        public static final int ADD = 0;
        public static final int SET = 1;
        public static final int GET = 2;
        public static final int JMP = 3;
        public static final int JGT = 4;
        public static final int END = 5;
    };

    public interface Value
        {
            void Set(Value v);
            void SetReal(double r);
            double Num();

        }

    static  class Number implements Value
    {
        double n;
        public void Set(Value v) {
            n = v.Num();
        }
        public void SetReal(double r) {
            n = r;
        }
        public double Num() {
            return n;
        }

        public Number(double x) {
            n = x;
        }
    }

    static int emit1(int b1, int b2, int b3, int b4) {
        return (b1<<24) + (b2<<16) + (b3<<8) + b4;
    }

    static int emit2(int b1, int b2, int b4) {
        return (b1<<24) + (b2<<16) + b4;
    }

    static int emit3(int b1, int b4) {
        return (b1<<24) + b4;
    }

    static int emit4(int b1) {
        return b1<<24;
    }

    public static void main(String[] args) {

            int[] ops = new int[13];
   
            ops[0] = emit2(OPER.GET, 0, 0);    // 0
            ops[1] = emit2(OPER.SET, 0, 10);   // x = 0
            ops[2] = emit2(OPER.GET, 0, 1);    // 1
            ops[3] = emit2(OPER.SET, 0, 11);   // y = 1
            ops[4] = emit2(OPER.GET, 0, 10);   // x
            ops[5] = emit2(OPER.GET, 1, 2);    // 100000000
            ops[6] = emit3(OPER.JGT, 11);      // if x > 100000000 goto
            ops[7] = emit2(OPER.GET, 0, 10);   // x
            ops[8] = emit2(OPER.GET, 1, 11);   // y
            ops[9] = emit1(OPER.ADD, 0, 0, 1); // _ = x + y
            ops[10] = emit2(OPER.SET, 0, 10);   // x = _
            ops[11] = emit3(OPER.JMP, 3);       // goto
            ops[12] = emit4(OPER.END);          // end

            Value[] reg = new Value[256];
            Value[] mem = new Value[1000];

            for(int i = 0; i < reg.length; i++) {
                reg[i] = new Number(0);
            }

            for(int i = 0; i < mem.length; i++) {
                mem[i] = new Number(0);
            }

            mem[0] = new Number(0);
            mem[1] = new Number(1);
            mem[2] = new Number(100000000);

            int ip = 0;

            loop:
            for (;;) {
                int w = ops[ip];

                int b4 = w & 0xFF;
                int b3 = (w >> 8) & 0xFF;
                int b2 = (w >> 16) & 0xFF;
                int b1 = (w >> 24) & 0xFF;

                switch (b1) {
                case OPER.GET:
                    reg[b2].Set(mem[b4]); break;
                case OPER.SET:
                    mem[b4].Set(reg[b2]); break;
                case OPER.ADD:
                    reg[b2].SetReal(reg[b3].Num() + reg[b4].Num()); break;
                case OPER.JMP:
                    ip = b4; break;
                case OPER.JGT:
                    if (reg[0].Num() > reg[1].Num()) {
                        ip = b4;
                    }
                    break;
                case OPER.END:
                    break loop;
                }
                ip++;

            }

            System.out.println(mem[10].Num());

    }
}


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Виртуальная машина на CP
СообщениеДобавлено: Среда, 22 Май, 2019 10:55 

Зарегистрирован: Вторник, 26 Январь, 2010 09:31
Сообщения: 717
Откуда: Барнаул
А что будет, если CASE заменить на IF ELSIF?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Виртуальная машина на CP
СообщениеДобавлено: Среда, 22 Май, 2019 11:26 

Зарегистрирован: Вторник, 30 Июнь, 2009 14:58
Сообщения: 1549
Я это проверял. Вроде не давало эффекта.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Виртуальная машина на CP
СообщениеДобавлено: Среда, 22 Май, 2019 11:53 

Зарегистрирован: Вторник, 26 Январь, 2010 09:31
Сообщения: 717
Откуда: Барнаул
Это хорошо, потому-что компилятор Активного Оберона чего-то там мудрит, и IF ELSIF в данном случае работает быстрее.
А если ветки упорядочить в соответствии с Add = 0; Set = 1; Get = 2; Jmp = 3; Jgt = 4; End = 5;
То тоже быстрее.
Но это всё хоть и печально, но на фоне того, что на выполнение MyTest.Do у меня тратится 13 секунд ...


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Виртуальная машина на CP
СообщениеДобавлено: Среда, 22 Май, 2019 14:48 

Зарегистрирован: Пятница, 11 Январь, 2019 21:33
Сообщения: 88
Не будет ли интересней поработать с результатом компиляции данного варианта DSL кода:
Код:
x = 0
y = 0.1
while x <= 10000000000000000 do
   x = x + y
end


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Виртуальная машина на CP
СообщениеДобавлено: Среда, 22 Май, 2019 17:44 

Зарегистрирован: Вторник, 29 Август, 2006 12:32
Сообщения: 2662
Откуда: Россия, Ярославль
Пооптимизируй компилер ББ. Всё станет намного быстрее.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Виртуальная машина на CP
СообщениеДобавлено: Среда, 22 Май, 2019 22:58 

Зарегистрирован: Вторник, 30 Июнь, 2009 14:58
Сообщения: 1549
Заглянул в шикарный профилировщик Go и увидел что из 2.5 секунд целая секундища уходит на одну строчку. Понял что компилятор не так умен при работе с интерфейсами как я ожидал. В итоге 1.4 секунды.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Виртуальная машина на CP
СообщениеДобавлено: Вторник, 28 Май, 2019 00:14 

Зарегистрирован: Вторник, 30 Июнь, 2009 14:58
Сообщения: 1549
Крутил вертел на досуге и так и сяк и не смог выжать из ББ ничего быстрее 3 секунд.
Мне кажется это как-то связано с 32 битностью ББ. Скорее всего имеют место какие-то накладные расходы при выполнении на 64 разрядном процессоре и ОС.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Виртуальная машина на CP
СообщениеДобавлено: Вторник, 28 Май, 2019 07:10 
Аватара пользователя

Зарегистрирован: Воскресенье, 09 Декабрь, 2018 15:14
Сообщения: 113
Откуда: Equestria
Так ты уже сравнил выхлопы дизассемблеров и нашёл 10 отличий?
Да и проблема скорей не в 32-битности, а в оптимизациях под современные архитектруры. Это дело не интуитивное, но "растактовки" под современные процессоры тоже существуют.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Виртуальная машина на CP
СообщениеДобавлено: Вторник, 28 Май, 2019 11:28 

Зарегистрирован: Вторник, 30 Июнь, 2009 14:58
Сообщения: 1549
Каким образом я могу посмотреть ассемблерный код? Да и какого конкретно куска кода? Ты же понимаешь что в Java, C# и Go нет ничего близкого BB во внутренней кухне. На Java в эти 1.6 секунды входит даже компиляция на лету. Что тут сравнивать можно?
Кроме того, если там какая-то оптимизация под конвейер процессора, то я все равно это по ассемблеру не пойму.

И оптимизация фиг знает какая тут может быть. SSE некуда притулить как кажется. Разворачивать цикл на BB я пробовал, это не помогло.
Замена REAL на INTEGER тоже не помогает. Я пробовал заменить ветки CASE на вызовы процедур и профилировать. Складывается ощущение что оно просто тупо медленно на всем. Будто машинный код в BB в целом неторопливо выполняется.
Попробую еще Go в 32 бита скомпилить. Может быть тоже медленнее будет.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Виртуальная машина на CP
СообщениеДобавлено: Вторник, 28 Май, 2019 12:57 
Модератор
Аватара пользователя

Зарегистрирован: Понедельник, 14 Ноябрь, 2005 18:39
Сообщения: 9459
Откуда: Россия, Орёл
Для ББ для машинного кода используй DevDecoder.

https://oberoncore.ru/bbcc/subs/start


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Виртуальная машина на CP
СообщениеДобавлено: Вторник, 28 Май, 2019 20:21 

Зарегистрирован: Вторник, 30 Июнь, 2009 14:58
Сообщения: 1549
Такс, ну примерно начинаю понимать почему Go быстрее: https://i.imgur.com/f2hRPmL.png
Оптимизирующий компилятор скорее всего выдаст более эффективный код просто сократив обмены с памятью.

ps Ассемблерный выхлоп Go смотрел, но там пипец ничего не понятно.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Виртуальная машина на CP
СообщениеДобавлено: Пятница, 31 Май, 2019 01:10 

Зарегистрирован: Вторник, 30 Июнь, 2009 14:58
Сообщения: 1549
Запустил код CP на gpcp для JVM. Скорость совсем немного меньше чем у решения на Java.
1.7 сек.
ps Да, кстати, использование в Java абстрактного класса вместо интерфейса ускоряет ее до 1.45 сек., что идентично Go (и как не странно быстрее C -O3)


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 41 ]  На страницу 1, 2, 3  След.

Часовой пояс: UTC + 3 часа


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

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


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
cron
Вся информация, размещаемая участниками на конференции (тексты сообщений, вложения и пр.) © 2005-2024, участники конференции «OberonCore», если специально не оговорено иное.
Администрация не несет ответственности за мнения, стиль и достоверность высказываний участников, равно как и за безопасность материалов, предоставляемых участниками во вложениях.
Без разрешения участников и ссылки на конференцию «OberonCore» любое воспроизведение и/или копирование высказываний полностью и/или по частям запрещено.
Powered by phpBB® Forum Software © phpBB Group
Русская поддержка phpBB