Experimental Physics and Industrial Control System
Hi Evgeniy,
On 12/23/2013 05:46 PM, Evgeniy wrote:
> The question is: if Mark got processing time for bi record 150
> microseconds 20 years ago should I have 1.5 microseconds for the same
> record on 100 times faster CPU ?
I have just timed how long it takes to process a simple database; my
recent-model MacBook Pro took 3.005 seconds to process the calc and ai
records from the example template's dbExample1.db file a million times,
thus the ai+calc pair processed once every 3 microseconds.
To do that I wrote a special record type (attached) that repeatedly
processes its target link. It is quite flexible, you can set it to do a
specific number of repetitions (REPM="Count", the count can be read
through the INP link or just put it into the VAL field which triggers
processing), or have it read the INP input link before or after each
operation to determine whether to continue or not (REPM="While" or "Until").
There is also a limit field STOP which sets the maximum number of
repetitions for protection. The value of STOP defaults to a million, but
you can override it yourself if you wish, up to 2^32-1. Note that
running this for several seconds can cause CA clients to disconnect, so
be careful with it!
> The same arithmetic question for scan. If its minimum period was 0.01
> seconds 20 years ago should I expect minimum 0.0001 seconds nowadays?
Periodic scans are quite complicated, since they rely on the underlying
operating system to implement a delay timer and reschedule the scan
thread after the specific delay has elapsed. Most OSs don't provide high
accuracy delay scheduling, so I don't expect we will ever be able to run
periodic scan threads at 10KHz.
- Andrew
--
Advertising may be described as the science of arresting the human
intelligence long enough to get money from it. -- Stephen Leacock
/*************************************************************************\
* Copyright (c) 2013 UChicago Argonne LLC, as Operator of Argonne
* National Laboratory.
* EPICS BASE is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
\*************************************************************************/
/* $Revision-Id$ */
/*
* Author: Andrew Johnson
* Date: 2013-12-27
*/
#include <stddef.h>
#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include "dbDefs.h"
#include "epicsPrint.h"
#include "alarm.h"
#include "dbAccess.h"
#include "dbEvent.h"
#include "dbFldTypes.h"
#include "errMdef.h"
#include "recSup.h"
#include "recGbl.h"
#include "dbCommon.h"
#define GEN_SIZE_OFFSET
#include "repeatRecord.h"
#undef GEN_SIZE_OFFSET
#include "epicsExport.h"
static long init_record(repeatRecord *prec, int pass)
{
if (pass && prec->repm == repeatREPM_Count) {
recGblInitConstantLink(&prec->inp, DBF_ULONG, &prec->val);
prec->udf = FALSE;
}
return 0;
}
static long process(repeatRecord *prec)
{
epicsUInt32 rept = prec->val;
epicsUInt32 i = 0;
prec->pact = TRUE;
prec->val = i;
recGblGetTimeStamp(prec);
db_post_events(prec, &prec->val, DBE_VALUE|DBE_LOG);
switch (prec->repm) {
case repeatREPM_None:
break;
case repeatREPM_Once:
dbScanFwdLink(&prec->tgt);
i++;
break;
case repeatREPM_Count:
if (prec->inp.type != CONSTANT) {
dbGetLink(&prec->inp, DBR_ULONG, &rept, 0, 0);
}
if (rept > prec->stop)
rept = prec->stop;
for (; i < rept; i++) {
dbScanFwdLink(&prec->tgt);
}
break;
case repeatREPM_While:
if (prec->inp.type != CONSTANT) {
dbGetLink(&prec->inp, DBR_ULONG, &rept, 0, 0);
}
while (rept) {
dbScanFwdLink(&prec->tgt);
if (++i >= prec->stop)
break;
if (prec->inp.type != CONSTANT) {
dbGetLink(&prec->inp, DBR_ULONG, &rept, 0, 0);
}
}
break;
case repeatREPM_Until:
do {
dbScanFwdLink(&prec->tgt);
if (++i >= prec->stop)
break;
if (prec->inp.type != CONSTANT) {
dbGetLink(&prec->inp, DBR_ULONG, &rept, 0, 0);
}
} while (!rept);
break;
default:
(void) recGblSetSevr(prec, SOFT_ALARM, INVALID_ALARM);
}
/* trigger alarm change monitors */
recGblResetAlarms(prec);
prec->udf = FALSE;
prec->val = i;
recGblGetTimeStamp(prec);
db_post_events(prec, &prec->val, DBE_VALUE|DBE_LOG);
/* process the forward link */
recGblFwdLink(prec);
prec->pact = FALSE;
return 0;
}
/* Create and export the Record Support Entry Table */
rset repeatRSET = {
RSETNUMBER, NULL, NULL, init_record, process
};
epicsExportAddress(rset, repeatRSET);
menu(repeatREPM) {
choice(repeatREPM_None, "None")
choice(repeatREPM_Once, "Once")
choice(repeatREPM_Count, "Count")
choice(repeatREPM_While, "While")
choice(repeatREPM_Until, "Until")
}
recordtype(repeat) {
include "dbCommon.dbd"
field(VAL, DBF_ULONG) {
prompt("Repeat")
asl(ASL0)
pp(TRUE)
}
field(REPM, DBF_MENU) {
prompt("Repeat Mode")
promptgroup(GUI_INPUTS)
interest(1)
menu(repeatREPM)
}
field(INP, DBF_INLINK) {
prompt("Input Link")
promptgroup(GUI_INPUTS)
interest(1)
}
field(TGT, DBF_FWDLINK) {
prompt("Target Link")
promptgroup(GUI_LINKS)
interest(1)
}
field(STOP, DBF_ULONG) {
prompt("Repeat limit")
promptgroup(GUI_INPUTS)
interest(1)
initial(1000000)
}
field(MVAL, DBF_ULONG) {
special(SPC_NOMOD)
interest(2)
}
}
- Replies:
- Re: Increasing scan rate to 10 kHz Keith Thorne
- Re: Increasing scan rate to 10 kHz Till Straumann
- Navigate by Date:
- Prev:
RE: Device support : TCP/IP packet Mark Rivers
- Next:
Re: Increasing scan rate to 10 kHz Keith Thorne
- Index:
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
<2014>
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
- Navigate by Thread:
- Prev:
RE: Device support : TCP/IP packet Mark Rivers
- Next:
Re: Increasing scan rate to 10 kHz Keith Thorne
- Index:
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
<2014>
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024