Real-Time - Newbie

Ulf Wiger <>
Mon Dec 6 14:44:59 CET 1999


On Mon, 6 Dec 1999, Leonard Weincier wrote:

len>Hi
len>
len>I have seen (briefly) some talk about soft real time properties of the
len>erlang runtime.
len>Could someone clarify this for me. 

Soft real-time, as opposed to hard real-time gives no guarantees about
response times. Erlang programs on a reasonably responsive computer will
have response times in the order of milliseconds normally. Under unusual
circumstances, response times can reach the 1-5 second range.

What are those unusual circumstances?

- Some calls in the I/O system are blocking, and normally quite fast,
  but if the I/O system is busy, the VM will block until they return
  (I've seen lseek() take 2-3 seconds when the disk was misconfigured)
  The Erlang I/O system is not threaded at the lowest level.

- Garbage collection can take a second or so on rapidly growing,
  very large heaps. It's usually not difficult to avoid such behaviour
  in your programs

As an example, I can tell you that the AXD 301 ATM Switch has a mean call
setup delay of 25 ms at 30 calls/s. To assess this, it's important to know
that one call uses about 8 internal messages and takes about 8 ms of CPU
time. So basically, the mean latency is about 17 ms in external and
internal signaling. Somewhere in the neighbourhood of 2 ms/message,
I would venture to guess.



len>I am looking at using erlang for a rules
len>engine and
len>am trying to asses feasability.

So basically, your latency requirements will depend on what your rules
engine is supposed to analyse. Another aspect is of course processing
efficiency.

I wrote a fuzzy-logic evaluator in Erlang to try to learn the basics in
fuzzy logic. When I implemented the classic "crane controller", I could see
that my Erlang controller, on a 16 MHz Ultra 10, behaved roughly like a
conventional controller on an 8-bit MCU (low-cost controller). This means
that each control cycle took about 1 ms (GC included, but not comm
latency).

I've attached the crane controller implementation. I used precalculated
membership functions to speed things up a bit.

Personally, I thought the result was rather satisfying. Performance
wasn't pitiful, if not great, and the controller implementation was 
reasonably simple to understand. Also, it's not too bad to be able
to modify the controller in runtime.

The big GC pauses I talked about above wouldn't be a problem here.

/Uffe
-- 
Ulf Wiger, Chief Designer AXD 301         <>
Ericsson Telecom AB                          tfn: +46  8 719 81 95
Varuvägen 9, Älvsjö                          mob: +46 70 519 81 95
S-126 25 Stockholm, Sweden                   fax: +46  8 719 43 44
-------------- next part --------------
-module(crane).

-compile(export_all).

-include("fuz.hrl").


-define(distance, (#mbf{min = -10, max = 40})).

distance(far) ->
    ?distance#mbf{name = {distance, far},
		  point1 = 10, slope1 = 0.07273, 
		  point2 = 23.75, slope2 = 0, area = 23.125};
distance(medium) ->
    ?distance#mbf{name = {distance, medium},
		  point1 = 5, slope1 = 0.148148, 
		  point2 = 11.75, slope2 = -0.08333, area = 9.375};
distance(close) ->
    ?distance#mbf{name = {distance, close},
		  point1 = 0, slope1 = 0.2, 
		  point2 = 5, slope2 = -0.2, area = 5};
distance(zero) ->
    ?distance#mbf{name = {distance, zero},
		  point1 = -5.125, slope1 = 0.195122, 
		  point2 = 0, slope2 = -0.20513, area = 5};
distance(too_far) ->
    ?distance#mbf{name = {distance, too_far},
		  point1 = nil, slope1 = 0, 
		  point2 = 0, slope2 = -0.195122, area = 7.4375}.


-define(angle, (#mbf{min = -90, max = 90})).

angle(pos_big) ->
    ?angle#mbf{name = {angle, pos_big},
	       point1 = 6.67000, slope1 = 0.023079, 
	       point2 = 50, slope2 = 0, area = 61.665};
angle(pos_small) ->
    ?angle#mbf{name = {angle, pos_small},
	       point1 = 0, slope1 = 0.149925, 
	       point2 = 6.67, slope2 = -0.023079, area = 25};
angle(zero) ->
    ?angle#mbf{name = {angle, zero},
	       point1 = -6.67, slope1 = 0.149925, 
	       point2 = 0, slope2 = -0.149925, area = 6.67};
angle(neg_small) ->
    ?angle#mbf{name = {angle, neg_small},
	       point1 = -50, slope1 = 0.023079, 
	       point2 = -6.67, slope2 = -0.149925, area = 25};
angle(neg_big) ->
    ?angle#mbf{name = {angle, neg_big},
	       point1 = nil, slope1 = 0, 
	       point2 = -6.67, slope2 = -0.023079, area = 61.665}.



-define(power, (#mbf{min = -30, max = 30, defuz_method = 'COM'})).

power(neg_high) ->
    ?power#mbf{name = {power, neg_high},
	       point1 = -30, slope1 = 0.3, 
	       point2 = -26.6667, slope2 = -0.0545453, area = 10.8333};
power(neg_medium) ->
    ?power#mbf{name = {power, neg_medium},
	       point1 = -26.667, slope1 = 0.0562493, 
	       point2 = -8.89, slope2 = -0.1125, area = 13.3335};
power(zero) ->
    ?power#mbf{name = {power, zero},
	       point1 = -8.33333, slope1 = 0.12, 
	       point2 = 0, slope2 = -0.12, area = 800};
power(pos_medium) ->
    ?power#mbf{name = {power, pos_medium},
	       point1 = 0, slope1 = 0.12, 
	       point2 = 8.33333, slope2 = -0.0545453, area = 13.3333};
power(pos_high) ->
    ?power#mbf{name = {power, pos_high},
	       point1 = 8.33333, slope1 = 0.0545453, 
	       point2 = 26.6667, slope2 = -0.3, area = 10.8333}.
    

%%
%% control() -> [{IF, THEN}].
%% IF :: = {'AND', [IfCond]} | {'OR', [IfCond]}
%% THEN ::= ThenCond
%% IfCond ::= {Variable, Value, LinguisticValue}
%% ThenCond ::= {Variable, LingusticValue}
%%
control(D, A) ->
    [{{'AND', [{distance, D, far}, {angle, A, zero}]}, 
      {power, pos_medium}},
     {{'AND', [{distance, D, far}, {angle, A, neg_small}]}, 
      {power, pos_high}},
     {{'AND', [{distance, D, medium}, {angle, A, neg_small}]}, 
      {power, pos_high}},
     {{'AND', [{distance, D, medium}, {angle, A, neg_big}]}, 
      {power, pos_medium}},
     {{'AND', [{distance, D, close}, {angle, A, pos_small}]}, 
      {power, neg_medium}},
     {{'AND', [{distance, D, close}, {angle, A, zero}]}, 
      {power, zero}},
     {{'AND', [{distance, D, close}, {angle, A, neg_small}]}, 
      {power, pos_medium}},
     {{'AND', [{distance, D, zero}, {angle, A, pos_small}]}, 
      {power, neg_medium}},
     {{'AND', [{distance, D, zero}, {angle, A, zero}]}, 
      {power, zero}}].
-------------- next part --------------
%%% fuz.hrl



-define(NORMAL, 100).
-define(HALF_NORMAL, 50).

-define(dbg(), ok).
%-define(dbg(), io:format("~p.~n", [{?MODULE, ?LINE}])).

-record(mbf, {name, min = 0, max = ?NORMAL, 
	      point1 = 0, slope1 = 0, 
	      point2 = 0, slope2 = 0, 
	      area = 0,
	      fuz_method = 'CMBF',   % currently ignored
	      defuz_method = 'COM'}). % Supported: 'MOM' and 'COM'


%% Defuzzyfication:
%% 'MOM' - Mean of Maximum. This is used to calculate the most
%%         probable linguistic value (and a typical numeric value).
%%         This is useful when calculating state.
%%         The value chosen is the one with the highest comination
%%         of (degree of truth) and weight. 
%%
%% 'COM' - Center of Maximum. This is used to calculate the best
%%         compromise. It returns a weighted value which is a 
%%         compromise of those rules which were at all true.


More information about the erlang-questions mailing list