Автор Тема: SYSTEM  (Прочитано 3343 раз)

ilovb

  • Hero Member
  • *****
  • Сообщений: 2538
  • just another nazi test
    • Просмотр профиля
    • Oberon systems
SYSTEM
« : Май 28, 2013, 08:13:08 pm »
Для тех кто плохо понимает зачем нужен псевдо-модуль SYSTEM в Оберонах и каким он должен быть на конкретной платформе вот интересная ссылочка из ETH: The Module SYSTEM

ilovb

  • Hero Member
  • *****
  • Сообщений: 2538
  • just another nazi test
    • Просмотр профиля
    • Oberon systems
Re: SYSTEM
« Ответ #1 : Май 28, 2013, 10:00:08 pm »
Насчет байта в Обероне...

Работа с байтами через "стандартный" систем может быть примерно такой:
MODULE MyTest;
    IMPORT SYSTEM, Log;
    CONST WORDSIZE = SIZE(INTEGER);   
   
    PROCEDURE Do*;
        VAR
            bytes: POINTER TO ARRAY OF INTEGER;
           
        PROCEDURE Get8(pos: INTEGER): INTEGER;
            VAR adr, val: INTEGER;
        BEGIN
            adr := SYSTEM.ADR(bytes^);
            ASSERT(pos < LEN(bytes) * WORDSIZE);
            SYSTEM.GET(adr + pos, val);
            RETURN val MOD 256;
        END Get8;
       
        PROCEDURE Put8(pos, val: INTEGER);
            VAR adr: INTEGER;
        BEGIN
            adr := SYSTEM.ADR(bytes^);
            ASSERT(pos < LEN(bytes) * WORDSIZE);
            ASSERT((val >= 0) & (val <= 255));
            SYSTEM.PUT(adr + pos, val);
        END Put8;
       
    BEGIN   
       
        NEW(bytes, (640 DIV WORDSIZE) * (480 DIV WORDSIZE));
       
        Put8(0, 0);
        Put8(1, 1);
        Put8(2, 255);
        Put8(3, 200);
       
        Log.Int(Get8(0));
        Log.Int(Get8(1));
        Log.Int(Get8(2));
        Log.Int(Get8(3));   
       
    END Do;
   
BEGIN
END MyTest.Do

Ну и не стоит забывать что в последней неофициальной редакции репорта от 01.07.2012 байт таки появился.

Цитировать
6.1. Basic types
The following basic types are denoted by predeclared identifiers. The associated operators are defined in 8.2, and the predeclared function procedures in 10.2. The values of a given basic type are the following:
BOOLEAN   the truth values TRUE and FALSE
CHAR   the characters of a standard character set
INTEGER   the integers
REAL   real numbers
BYTE   the integers between 0 and 255
SET   the sets of integers between 0 and 31
The type BYTE is compatible with the type INTEGER, and vice-versa.

Однако, имхо, это спорное решение.
Также спорным является SET, который прибит гвоздями к 32 битам. Что будет если делать ORD() при 16 бит INTEGER неизвестно....

ilovb

  • Hero Member
  • *****
  • Сообщений: 2538
  • just another nazi test
    • Просмотр профиля
    • Oberon systems
Re: SYSTEM
« Ответ #2 : Май 28, 2013, 10:38:45 pm »
И еще...

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

Т.е. вполне можно обойтись и "стандартным" SYSTEM. Просто в своем приложении нужно предусмотреть набор платформозависимых модулей под каждую целевую платформу: Platform_x86, Platform_x64, Platform_ARM etc

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

Если нужно выжать все соки, то можно и в маш. кодах реализовать некоторые процедуры.

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

ps Репорт требует уточнения, да. Думаю что Вирт сейчас этим и занимается.

vlad

  • Hero Member
  • *****
  • Сообщений: 1391
    • Просмотр профиля
Re: SYSTEM
« Ответ #3 : Май 28, 2013, 11:14:36 pm »
ps Репорт требует уточнения, да. Думаю что Вирт сейчас этим и занимается.

Не думаю. Неинтересно это...

ilovb

  • Hero Member
  • *****
  • Сообщений: 2538
  • just another nazi test
    • Просмотр профиля
    • Oberon systems
Re: SYSTEM
« Ответ #4 : Май 28, 2013, 11:26:55 pm »
Ну можно спросить у него...  ;)

По поводу этого http://oberspace.dyndns.org/index.php/topic,484.0.html
лично я бы не использовал Get8/Put8. Мне кажется что гораздо проще все вычисления делать на INTEGER и просто сделать одну процедуру PackToBytes(src: ARRAY OF INTEGER, adr: INTEGER), которая просто пересылает данные в видеобуфер, попутно упаковывая INTEGER'ы в байты.

valexey_u

  • Hero Member
  • *****
  • Сообщений: 3013
    • Просмотр профиля
Re: SYSTEM
« Ответ #5 : Май 28, 2013, 11:29:48 pm »
Ну можно спросить у него...  ;)

По поводу этого http://oberspace.dyndns.org/index.php/topic,484.0.html
лично я бы не использовал Get8/Put8. Мне кажется что гораздо проще все вычисления делать на INTEGER и просто сделать одну процедуру PackToBytes(src: ARRAY OF INTEGER, adr: INTEGER), которая просто пересылает данные в видеобуфер, попутно упаковывая INTEGER'ы в байты.
Дорого.
Y = λf.(λx.f (x x)) (λx.f (x x))

ilovb

  • Hero Member
  • *****
  • Сообщений: 2538
  • just another nazi test
    • Просмотр профиля
    • Oberon systems
Re: SYSTEM
« Ответ #6 : Май 28, 2013, 11:31:49 pm »
Ну дешевле наверно только специальные команды пересылки....

ps Или ты про память?

ilovb

  • Hero Member
  • *****
  • Сообщений: 2538
  • just another nazi test
    • Просмотр профиля
    • Oberon systems
Re: SYSTEM
« Ответ #7 : Май 28, 2013, 11:48:50 pm »
Блин, с арихметикой не дружу...  :)

так должно быть там (640 * 480 DIV WORDSIZE)

valexey_u

  • Hero Member
  • *****
  • Сообщений: 3013
    • Просмотр профиля
Re: SYSTEM
« Ответ #8 : Май 28, 2013, 11:50:23 pm »
Ну дешевле наверно только специальные команды пересылки....

ps Или ты про память?
Я про всё. И про лишние копирования, и про то что в результате у нас объем данных увеличивается в 4 раза, что вполне вероятно приведет к тому, что оно не влезет в кеш процессора (и начнет в результате дико тормозить), и про то что это будет да, лишняя память.
Y = λf.(λx.f (x x)) (λx.f (x x))

ilovb

  • Hero Member
  • *****
  • Сообщений: 2538
  • just another nazi test
    • Просмотр профиля
    • Oberon systems
Re: SYSTEM
« Ответ #9 : Май 29, 2013, 12:55:44 am »
Тогда маш. код  :) Ведь тебя не пугает написание двух маленьких процедур в маш. кодах?  ;)

Кстати, поправил Put8:
PROCEDURE Put8(pos, val: INTEGER);
    VAR adr, int: INTEGER;
BEGIN
    adr := SYSTEM.ADR(bytes^);
    ASSERT(pos < LEN(bytes) * WORDSIZE);
    ASSERT((val >= 0) & (val <= 255));
    SYSTEM.GET(adr + pos, int);
    SYSTEM.PUT(adr + pos, SYSTEM.VAL(SET, int) - {0..7} + SYSTEM.VAL(SET, val));
END Put8;

ps Наверно есть более элегантные и производительные способы, но нужно иметь опыт чтобы быстро сообразить...
« Последнее редактирование: Май 29, 2013, 12:57:46 am от ilovb »

ilovb

  • Hero Member
  • *****
  • Сообщений: 2538
  • just another nazi test
    • Просмотр профиля
    • Oberon systems
Re: SYSTEM
« Ответ #10 : Май 29, 2013, 08:20:34 am »
valexey, вот такой код отрабатывает у меня за 2 секунды
MODULE MyTest;
    IMPORT SYSTEM, Log;
    CONST WORDSIZE = SIZE(INTEGER);   
   
    PROCEDURE Do*;
        VAR
            ints: POINTER TO ARRAY OF INTEGER;
            bytes: POINTER TO ARRAY OF INTEGER;
            i: INTEGER;
           
        PROCEDURE Get8(pos: INTEGER): INTEGER;
            VAR adr, val: INTEGER;
        BEGIN
            adr := SYSTEM.ADR(bytes^);
            ASSERT(pos < LEN(bytes) * WORDSIZE);
            SYSTEM.GET(adr + pos, val);
            RETURN val MOD 256;
        END Get8;
       
        PROCEDURE Put8(pos, val: INTEGER);
            VAR adr, int: INTEGER;
        BEGIN
            adr := SYSTEM.ADR(bytes^);
            ASSERT(pos < LEN(bytes) * WORDSIZE);
            ASSERT((val >= 0) & (val <= 255));
            SYSTEM.GET(adr + pos, int);
            SYSTEM.PUT(adr + pos, SYSTEM.VAL(SET, int) - {0..7} + SYSTEM.VAL(SET, val));
        END Put8;
       
        PROCEDURE PackToBytes(VAR src: ARRAY OF INTEGER; adr: INTEGER);
            VAR i: INTEGER;
        BEGIN
            FOR i := 0 TO LEN(src) - 1 BY 4 DO
                SYSTEM.PUT(adr + i, src[i] +
                    SYSTEM.LSH(src[i+1],  8) +
                    SYSTEM.LSH(src[i+2], 16) +
                    SYSTEM.LSH(src[i+3], 24));
            END;
        END PackToBytes;
       
    BEGIN   
       
        NEW(ints,  (640 * 480 * 3));
        NEW(bytes, (640 * 480 * 3 DIV WORDSIZE));
       
        (*
        Put8(0, 0);
        Put8(1, 1);
        Put8(2, 255);
        Put8(3, 200);
        *)
       
        ints[0] := 0;
        ints[1] := 1;
        ints[2] := 255;
        ints[3] := 200;
       
        FOR i := 0 TO 1000 DO
            PackToBytes(ints, SYSTEM.ADR(bytes^));
        END;
       
        Log.Int(Get8(0)); Log.Ln;
        Log.Int(Get8(1)); Log.Ln;
        Log.Int(Get8(2)); Log.Ln;
        Log.Int(Get8(3)); Log.Ln;
       
    END Do;
   
BEGIN
END MyTest.Do

ilovb

  • Hero Member
  • *****
  • Сообщений: 2538
  • just another nazi test
    • Просмотр профиля
    • Oberon systems
Re: SYSTEM
« Ответ #11 : Май 29, 2013, 08:53:08 am »
Ну и такой вариант совсем немного медленнее:
PROCEDURE PackToBytes2(VAR src, dst: ARRAY OF INTEGER);
    VAR i, j: INTEGER;
BEGIN
    j := 0;
    FOR i := 0 TO LEN(src) - 1 BY 4 DO
        dst[j] := src[i] +
            SYSTEM.LSH(src[i+1],  8)+
            SYSTEM.LSH(src[i+2], 16)+
            SYSTEM.LSH(src[i+3], 24);
        INC(j);
    END;
END PackToBytes2;

А в Обероне это даже без SYSTEM будет