Rambler's Top100
"Knowledge itself is power"
F.Bacon
Поиск | Карта сайта | Помощь | О проекте | ТТХ  
 Базарная площадь
  
О разделе

Основная страница

Группы обсуждений


Тематический каталог обсуждений

Архив

 
 К н и г и
 
Книжная полка
 
 
Библиотека
 
  
  
 


Поиск
 
Поиск по КС
Поиск в статьях
Яndex© + Google©
Поиск книг

 
  
Тематический каталог
Все манускрипты

 
  
Карта VCL
ОШИБКИ
Сообщения системы

 
Форумы
 
Круглый стол
Новые вопросы

 
  
Базарная площадь
Городская площадь

 
   
С Л С

 
Летопись
 
Королевские Хроники
Рыцарский Зал
Глас народа!

 
  
ТТХ
Конкурсы
Королевская клюква

 
Разделы
 
Hello, World!
Лицей

Квинтана

 
  
Сокровищница
Подземелье Магов
Подводные камни
Свитки

 
  
Школа ОБЕРОНА

 
  
Арсенальная башня
Фолианты
Полигон

 
  
Книга Песка
Дальние земли

 
  
АРХИВЫ

 
 

Сейчас на сайте присутствуют:
 
  
 
Во Флориде и в Королевстве сейчас  10:16[Войти] | [Зарегистрироваться]
Обсуждение темы:
Оберон-технология: особенности и перспективы


Тематика обсуждения: Оберон-технология. Особенности, перспективы, практическое применение. 

Количество сообщений на странице

Порядок сортировки сообщений
Новое сообщение вверху списка (сетевая хронология)
Первое сообщение вверху списка (обычная хронология)

Перейти на конкретную страницу по номеру


Всего в теме 6256 сообщений

Добавить свое сообщение

Отслеживать это обсуждение

Обсуждение из раздела
Школа ОБЕРОНА

<<<... | 6056—6047 | 6046—6037 | 6036—6027 | ...>>>
Всего сообщений в теме: 6256; страниц: 626; текущая страница: 22


№ 6046   14-12-2007 18:28 Ответить на это сообщение Ответить на это сообщение с цитированием
Ответ на »сообщение 6045« (pepper)
___________________________
Это - не пример!
Это схема уже построенного цикла. Дайте мне этот цикл с содержанием - в 95% он может быть перестроен по грамотным правилам без вложенных проверок.

Споры про break тут уже бушевали... Народ не знает базовых схем алгоритмики и понятия инварианта и суёт свои "велосипеды", пытаясь доказать, что без break никак.

Вспомним Дейкстру "Дисциплину программирования" (http://europrog.ru/book/dped1978r.pdf)
"Первейшим достоинством алгоритма является потенциальная компактность рассуждений, на которых может основываться проникновение в его сущность. Как только эта компактность потеряна, алгоритм в значительной степени теряет право на существование..."
и конкретно:
"Мы представляем себе функционирование конструкции S достаточно хорошо, если только знаем, как соответствующий ей преобразователь предикатов действует над любым постусловием".

Надо бы ввести отраслевой стандарт, чтобы каждый предлагающий свой вариант конструкции цикла (а вариантов циклов с выходом из середины ого сколько можно наизобретать - а на практике "наизобретовывают" ещё больше, чем я тут могу представить :-) ), обосновывал её право на существование, выводя для неё преобразователь предикатов. Пока не умахается для каждого "велосипеда" выводить. А иначе считать "алгоритм потерявшим право на существование" :-)



№ 6045   14-12-2007 18:03 Ответить на это сообщение Ответить на это сообщение с цитированием
Ответ на »сообщение 6039« (Илья Ермаков)
___________________________

А в С-шных программах break на break-е - а каждый break, как и goto - это палка в колёса оптимизатору.


Вот пример с кучей break:

while (condition1())
{
    ...
    if (condition2())
        break;
    ... 
    if (condition3())
        break;
    ...
}


А вот без break:

bool flag2 = true;
bool flag3 = true;
while (condition1() && flag2 && flag3)
{
    ...
    flag2 = condition2()
    if (flag2)
    {
        ...
        flag3 = condition3();
        if (flag3)
        {
            ...
        }
    }
}


Вы всерьез думаете, что во втором случае у оптимизатора меньше работы? ;) Кстати, на этом же примере видно, как серьезно может пострадать читаемость, если возводить "правильность циклов без break" в догму. Особенно если писатель не придумал хороших названий для flag2 и flag3 ;)

P.S. Кстати, придумывание правильных названий занимает существенное время при кодировании. Поэтому чем их меньше и чем они локальнее - тем лучше.


№ 6044   14-12-2007 07:48 Ответить на это сообщение Ответить на это сообщение с цитированием
Ответ на »сообщение 6042« (Geniepro)
___________________________
>>> Вот любопытно, насколько просто или сложно будет это сделать, как стабильно это будет работать, и сколько времени будет потрачено на пересылку этих сообщений, как будет замедляться программа в зависимости от числа акторов сколько вообще акторов сможет максимально запуститься... В смысле, насколько легковесны Ваши акторы? ;о)
Вообщем, просто - сложно, понятия явно относительны. Мне это удалось сделать просто и быстро.
На счет стабильности - пересылка работает стабильно, но я заметил некоторые странности при удалении объектов. Спасибо за предложенный тест, буду разбираться.

Актеров запустить можно столько, сколько памяти есть в системе. Для 32-битных систем это около 5 млн., но это "голых". Если они будут нести в себе дополнительные данные, то их число соответственно уменьшится.

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

Код программы:
Это полностью готовый к запуску код. Можно его подставить в пример ping-pong, либо создать новый проект на его основе.
Если что, то скачать пакет библиотеки acto, как всегда можно здесь:
http://sourceforge.net/projects/act-o

#include <multiprog.h>

#include <iostream>
#include <vector>
#include <conio.h>

using namespace multiprog;


// Кол-во элементов цепи
static const size_t NODES      =    1000 * 1000;
static const size_t STOP_VALUE = 1 * 1000 * 1000;


// Desc: Узел цепи
class Node : public acto::implementation_t {
public:
    struct msg_init : public acto::msg_t {
        acto::actor_t  next;
    };

    struct msg_marker : public acto::msg_t {
        size_t      value;
    };

public:
    Node() {
        Handler< msg_init  >(&Node::doInit);
        Handler< msg_marker >(&Node::doMarker);
    }

private:
    void doInit(acto::actor_t& sender, const msg_init& msg) {
        m_next = msg.next;
    }

    void doMarker(acto::actor_t& sender, const msg_marker& msg) {
        msg_marker  result(msg);
        // -
        if (result.value == STOP_VALUE)
            context.send(result);
        else {
            result.value += 1;
            m_next.send(result);
        }
    }

private:
    acto::actor_t  m_next;
};

// Desc:
class Ring : public acto::implementation_t {
public:
    struct msg_init : public acto::msg_t { };

public:
    Ring() {
        Handler< msg_init >  (&Ring::doInit);
        Handler< msg_marker >(&Ring::doMarker);
    }

private:
    typedef Node::msg_marker    msg_marker;

    // -
    void doMarker(acto::actor_t& sender, const msg_marker& msg) {
        __int64  end;
        __int64  frq;
        // -
        ::QueryPerformanceCounter  ((LARGE_INTEGER*)&end);
        ::QueryPerformanceFrequency((LARGE_INTEGER*)&frq);
        // -
        std::cout << "marker value : " << msg.value            << std::endl;
        std::cout << "time ticks  : " << end - m_start        << std::endl;
        std::cout << "time seconds : " << (end - m_start) / frq << std::endl;

        for (size_t i = 0; i < m_nodes.size(); i++)
            acto::destroy(m_nodes[i]);
    }
    // -
    void doInit(acto::actor_t& sender, const msg_init& msg) {
        if (NODES > 0) {
            m_nodes.reserve(NODES);
            // 1. Создать элементы цепи
            for (size_t i = 0; i < NODES; i++)
                m_nodes.push_back(acto::instance_t< Node >(self));

            // 2.
            for (size_t i = 1; i < m_nodes.size(); i++)
                setLink(m_nodes[i-1], m_nodes[i]);
            // Замкнуть кольцо
            setLink(m_nodes.back(), m_nodes.front());

            // 3. Запустить
            {
                std::cout << "start passing..." << std::endl;
                // -
                ::QueryPerformanceCounter((LARGE_INTEGER*)&m_start);
                // -
                Node::msg_marker    marker;
                marker.value = 0;
                m_nodes.front().send(marker);
            }
        }
    }

private:
    void setLink(acto::actor_t& from, acto::actor_t& to) {
        Node::msg_init  msg;
        msg.next = to;
        // -
        from.send(msg);
    }

private:
    __int64                        m_start;
    std::vector< acto::actor_t >    m_nodes;
};

//----------------------------------------------------------------
int main()
{
    std::cout << "--- start acto ---" << std::endl;
    // Инициализировать библиотеку.
    acto::startup();
    {
        acto::actor_t ring = acto::instance_t< Ring >();
        // -
        Ring::msg_init  msg;
        ring.send(msg);
        // -
        _getch();
    }
    std::cout << "--- end acto ---" << std::endl;
    acto::shutdown();
    // Выполнение программы закончено
    std::cout << ": end" << std::endl;
    _getch();
    // -
    return 0;
}


№ 6043   14-12-2007 05:25 Ответить на это сообщение Ответить на это сообщение с цитированием
Ответ на »сообщение 6038« (pepper)
___________________________

VC6.0 не оптимизирует плавающую точку в принципе. Возьмите современный интеловский компилятор, получите факторы...

Спасибо, мысль понятна, от комментариев воздержусь.


№ 6042   14-12-2007 03:04 Ответить на это сообщение Ответить на это сообщение с цитированием
Ответ на »сообщение 6020« (Стэн)
___________________________

Кстати, я ее тестировал до более чем 1'000'000 активных объектов, и все очень даже стабильно...

Кстати, вот мне любопытно, как будет выглядеть и работать с Вашими акторами простенькая программа, в которой, скажем, сто тысяч акторов образуют кольцо и пересылают друг другу сообщения по этому кольцу. Примерно так: главная функция программы создаёт n акторов, даёт им ссылки на следующего (первому -- на второго, второму -- на третьего, ..., n-му -- на первого), затем посылает первому число ноль (int32, например), первый увеличивает его на единичку и отсылает второму и т.д. до тех пор, пока следующий актор не обнаружит, что это сообщение содержит число m (ну, например, миллион). Затем это число отсылается главной функции, которая его просто печатает...

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

ЗЫ. Вот для ориентира код на Хаскелле:

import IO
import Time
import System
import Control.Monad
import Control.Concurrent

defMsgs = 1000000 :: Int -- Дефолтные количества сообщений и потоков
defThrs = 1000    :: Int

main = do
    hSetBuffering stdout NoBuffering

    args <- getArgs
    let (numThr, numMsg) = case map read args of
                                t:m:_  -> (t, m)
                                t:_    -> (t, defMsgs)
                                _      -> (defThrs, defMsgs)

    putStr $ show numThr ++ ", " ++ show numMsg ++ " Timings: "
    t1 <- getClockTime

    -- Создаём каналы связи для каждого потока
    (mainCh:thrChs) <- forM [0..numThr] $ \_ -> newChan

    t2 <- getClockTime; putStr $ showTimeDif t2 t1 -- Время на создание каналов

    -- Запускаем потоки, указав им каналы: свой и следующего потока
    thrs <- forM [0..numThr-1] $ \i -> do
            forkIO $ newThr numMsg        -- Сколько всего будет пересылок
                            mainCh        -- Куда отправить результат
                            (thrChs !! i) -- Откуда принимать сообщение
                            (thrChs !! if i == numThr-1 then 0 else i+1) -- и куда его переслать

    t3 <- getClockTime; putStr $ "  " ++ showTimeDif t3 t2 ++ "  " -- Время на запуск потоков

    -- Запустим цепочку пересылок сообщений
    writeChan (thrChs !! 0) 0

    -- Ждём конечного результата
    putStr . show =<< readChan mainCh

    t4 <- getClockTime -- время на пересылку сообщений и общее время работы
    putStrLn $ "  " ++ showTimeDif t4 t3 ++ "  Total time: " ++ showTimeDif t4 t1

newThr max mainCh myCh nextCh = do
    num <- readChan myCh
    if num == max then do writeChan mainCh num
                  else do writeChan nextCh $! num + 1
                          newThr max mainCh myCh nextCh

showTimeDif ft st = show(tdHour td) ++ ":" ++ show(tdMin td) ++ ":"
                ++ show nsecs      ++ "." ++ snms
  where
    td          = ft `diffClockTimes` st
    secs        = tdSec    td
    ms          = tdPicosec td `div` 1000000000
    (nsecs, nms) = if ms < 0 then (secs - 1, ms + 1000) else (secs, ms)
    snms        = reverse $ take 3 $ (reverse $ show nms) ++ "000"



№ 6041   14-12-2007 02:25 Ответить на это сообщение Ответить на это сообщение с цитированием
Ответ на »сообщение 6015« (Илья Ермаков)
___________________________

Не сочтите за серость и дремучий провинциализм... Но что це такое буде - SVG?

SVG -- довольно серьёзная вещь, сейчас она широко популярна в узких кругах. С помощью SVG предлагается, например, делать веб-приложения, заменив им всякие там проприетарные Macromedia Flash, поддержка SVG есть во всех нормальных браузерах, в отличии от Flash...
Не знаю как Вам, а мне нравится вот эта апплетка на SVG: http://www.croczilla.com/svg/samples/svgtetris/svgtetris.svg
И ещё куча разных примерчиков: http://www.croczilla.com/svg/samples/


№ 6040   14-12-2007 01:59 Ответить на это сообщение Ответить на это сообщение с цитированием
Ответ на »сообщение 6028« (Илья Ермаков)
___________________________
>>> Плюс выйти на распределённость этого механизма в С++ очень трудно, если вообще возможно.
Вообще-то, выйти можно, но там действительно немного другой механизм и сложность чуть больше:
http://sobjectizer.sourceforge.net/

Однако лично у меня есть очень большие сомнения относительно необходимости выводить именно этот механизм на уровень распределенности. Часто приходится сталкиваться, например, у меня в блоге писали:
http://stanonwork.blogspot.com/2007/07/blog-post_18.html#c1516085987407081387
с тем, что раз модель актеров, то какая разница локально, распределено?! Сообщение отправили, сообщение получили... Но разница есть и весьма большая. Мы ведь не ожидаем, что посреди выполнения какой-то функции отключится модуль памяти, либо сгорит процессор. А если и ожидаем, то единственное, что обычно делаем - старый компьютер выбрасываем, новый покупаем, а программу перезапускаем. В сети все по-другому: вполне нормально, что часть компьютеров выйдет из строя, однако наша система должна продолжать работать. В результате, все это порожадет совершенно разные требования к программам, которые работают распределено, и программам, которые работают просто параллельно...

>>> Так вот над каким вопросом я думаю - почему тогда не оставить блокирующую посылку сообщения с ожиданием ответа на уровне примитивов? (в эрланге-то ясно почему, ибо язык функциональный, состояния исключены). С другой стороны, это усложнит диспетчерирование потоков, т.к. сейчаc в своей библиотеке между посылкой запроса и приходом ответа Вы можете перекинуть поток на "оживление" любого другого актёра, а в этом случае контекст потока нужно сначала сохранить, потом опять восстановить... Либо вообще не трогать этот поток, но тогда количество одновременно оживляемых клиент-серверных актёров резко снизится...
Все зависит от того, какой результат хочется получить. Мне надо было получить систему с множеством легких активностей, работающую поверх тяжелых потоков ОС. Поэтому поток трогать в любом случае надо. Если у Вас их не так много, то можно об этом подумать...
В вопросе о том, как переключать - можно рассмотреть два варианта: 1) сохранять контекст 2) с помощью предкомпиляции разбивать один логический метод на несколько физических - до блокировки, и после блокировки.
Ну и, - нужно ли оставить блокировку? Да, для некоторых задач это бы облегчило написание кода, но это, как мне думается, надо аккуратно заворачивать в высокоуровневое представление, а потом транслировать в примитивы runtime'а, в котором этих блокировок нет из-за требования обеспечить множество легких активностей.
Посмотрите вот эту ссылку:
www.stanford.edu/class/cs240/readings/capriccio-sosp-2003.pdf
Также получается многоуровневое решение, с асинхронным API внизу.


№ 6039   14-12-2007 01:26 Ответить на это сообщение Ответить на это сообщение с цитированием
Ответ на »сообщение 6035« (Qr)
___________________________

Ответ на »сообщение 6009« (Илья Ермаков)
Ну вот хоть какое-то число (+/-10%) названо, правда что оно означает пока все еще загадка.
Если речь o сравнении xds vs Visual C++, то xds может проигрывать процентов 20-30, что действительно очень неплохо. Если же сравнивать ББ и Visual C++, то ББ будет проигрывать уже ФАКТОР 2-3. Алгоритмикой будем исправлять? Или может все-же сначала стоит действительно довести ББ до ума в смысле производительности, а народ потом и сам потянется?

Народ и так тянется. А чем больше будет промышленных применений, тем скорее можно надеяться, что Excelsior сделают из XDS оптимизатор для ББ. А ваять оптимизатор на коленках неизвестно для чего - знаете, "не зная броду...".

По поводу "проигрывать процентов 20-30" - я ж говорю, зависит от версии. Если освежить оптимизатор и осовременить систему команд, то будет ровно наоборот, как уже было когда-то в 90-х, когда с XDS не мог тягаться ни один С-компилятор. Это ж теоретически обосновано - язык с регулярным синтаксисом и отсутствием неструктурных операторов оптимизируется гораздо лучше (см. Ахо, Сети, Ульман "Компиляторы"). А в С-шных программах break на break-е - а каждый break, как и goto - это палка в колёса оптимизатору.

А производительность - штука весьма тонкая. Например, на неё приличное влияние (в интеграле, по общей "реактивности" системы) оказывает архитектура. Есть много примеров, когда страшилки, высосанные из пальца, расходятся с практикой (например, теоретически микроядро должно ощутимо замедлять работу ОС, а бывает, что Unix, запущенный в пользовательском режиме поверх микроядра, начинает работать эффективнее - про такой случай на недавнем семинаре, кстати, рассказывал А.С. Косачев, вед.н.с. Института системного программирования РАН).

И вообще, читать Дейкстру :-)
"Возможность использования языков программирования в качестве средства общения с существующими автоматическими вычислителями, в течение долгого времени рассматривалась как их наиболее важное свойство. ... Как огорчительное следствие мы нередко обнаруживаем, что аномалии существующих вычислительных машин старательно воспроизводятся в языках программирования, прич\"ем это происходит в ущерб интеллектуальной управляемости программ, выражаемых на таком языке (как будто программирование и без этих аномалий не было уже достаточно трудным!) ... Я рассматриваю язык программирования преимущественно как средство для описания (потенциально весьма сложных) абстрактных конструкций."


№ 6038   14-12-2007 00:10 Ответить на это сообщение Ответить на это сообщение с цитированием
Ответ на »сообщение 6037« (info21)
___________________________


там смотреть страницу 8.


VC6.0 не оптимизирует плавающую точку в принципе. Возьмите современный интеловский компилятор, получите факторы...


№ 6037   13-12-2007 23:32 Ответить на это сообщение Ответить на это сообщение с цитированием
Ответ на »сообщение 6036« (info21)
___________________________

Откуда сии факторы-то? У меня вот другие были:
http://www.inr.ac.ru/~blackbox/Oberon.Day/talks/ftkachov.pdf


там смотреть страницу 8.


<<<... | 6056—6047 | 6046—6037 | 6036—6027 | ...>>>
Всего сообщений в теме: 6256; страниц: 626; текущая страница: 22


Добавить свое сообщение

Отслеживать это обсуждение

Дополнительная навигация:
Количество сообщений на странице

Порядок сортировки сообщений
Новое сообщение вверху списка (сетевая хронология)
Первое сообщение вверху списка (обычная хронология)

Перейти на конкретную страницу по номеру
  
Время на сайте: GMT минус 5 часов

Если вы заметили орфографическую ошибку на этой странице, просто выделите ошибку мышью и нажмите Ctrl+Enter.
Функция может не работать в некоторых версиях броузеров.

Web hosting for this web site provided by DotNetPark (ASP.NET, SharePoint, MS SQL hosting)  
Software for IIS, Hyper-V, MS SQL. Tools for Windows server administrators. Server migration utilities  

 
© При использовании любых материалов «Королевства Delphi» необходимо указывать источник информации. Перепечатка авторских статей возможна только при согласии всех авторов и администрации сайта.
Все используемые на сайте торговые марки являются собственностью их производителей.

Яндекс цитирования