updated pvDatabaseCPP.html and TODO
This commit is contained in:
@ -4,5 +4,5 @@
|
||||
<h2>Must test record delete.</h2>
|
||||
<p>Must test removing a record from the PVDatabase while a pvAccess client
|
||||
is attached. Also why do both unlisten and detach exists?</p>
|
||||
<h2>create more regresion tests</h2>
|
||||
<h2>create more regression tests</h2>
|
||||
<p>Currently only some simple tests exist. Most of the testing has been via the examples</p>
|
@ -13,7 +13,7 @@ Must test removing a record from the PVDatabase while a pvAccess client
|
||||
is attached. Also why do both unlisten and detach exists?
|
||||
|
||||
|
||||
create more regresion tests
|
||||
create more regression tests
|
||||
----------------
|
||||
|
||||
Currently only some simple tests exist. Most of the testing has been via the examples
|
||||
|
@ -38,7 +38,7 @@
|
||||
<h1>pvDatabaseCPP</h1>
|
||||
<!-- Maturity: Working Draft or Request for Comments, or Recommendation, and date. -->
|
||||
|
||||
<h2 class="nocount">EPICS v4 Working Group, Working Draft, 11-August-2014</h2>
|
||||
<h2 class="nocount">EPICS v4 Working Group, Working Draft, 09-Oct-2014</h2>
|
||||
<dl>
|
||||
<dt>Latest version:</dt>
|
||||
<dd><a
|
||||
@ -78,9 +78,9 @@ V4 control system programming environment:<br />
|
||||
|
||||
<h2 class="nocount">Status of this Document</h2>
|
||||
|
||||
<p>This is the 11-August-2014 version of of pvDatabaseCPP.</p>
|
||||
</p>
|
||||
<p>This is the 09-Oct-2014 version of of pvDatabaseCPP.</p>
|
||||
<p>This version is a complete implementation of what is described in this manual.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div id="toc">
|
||||
@ -92,7 +92,7 @@ V4 control system programming environment:<br />
|
||||
<h2>Introduction</h2>
|
||||
<h3>Overview</h3>
|
||||
<p>The main purpose of this project to make it easier to implement services that are accessed via pvAccess.
|
||||
This project supplies is a complete implementation of the server side of pvAccess.
|
||||
This project supplies a complete implementation of the server side of pvAccess.
|
||||
All that a service has to provide is a top level PVStructure and a process method.
|
||||
A service can be run as a main process or can be part of a V3 IOC.
|
||||
Thus services can be developed that interact with V3 records, asynDriver,
|
||||
@ -109,25 +109,25 @@ The local provider provides access to the records in the pvDatabase.
|
||||
This local provider is accessed by the remote pvAccess server.
|
||||
A record is smart because code can be attached to a record, which is accessed via a method named process.</p>
|
||||
|
||||
<p>This document describes components that provide the following features:
|
||||
<p>This document describes components that provide the following features:</p>
|
||||
<dl>
|
||||
<dt>database<dt>
|
||||
<dt>database</dt>
|
||||
<dd>This encapsulates the concept of a database of memory resident smart records.
|
||||
The two main components are:
|
||||
<dl>
|
||||
<dt>pvRecord</dt>
|
||||
<dd>This encapsulates the concept of a smart record. It can be processed.
|
||||
Changes to field values can be trapped. A record can be locked.</dd>
|
||||
<dt>pvDatabase<dt>
|
||||
<dt>pvDatabase</dt>
|
||||
<dd>This is a database of pvRecords.
|
||||
Records can be added and removed from a database.</dd>
|
||||
</dl>
|
||||
</dd>
|
||||
<dt>pvAccess</dt>
|
||||
<dd>This is a complete implementation of ChannelProvider and Channel
|
||||
as defined by pvAccess.
|
||||
It is used by the server side of pvAccess to attach to pvRecords.
|
||||
This component also provides a C++ implementation
|
||||
of the monitor and pvCopy components from pvIOCJava</dd>
|
||||
</dd>
|
||||
<dt>Main and V3IOC</dt>
|
||||
<dd>The pvDatabase can be provided via a Main program or can be part
|
||||
of a V3IOC. In the later case the IOC has both a database of V3 Records
|
||||
@ -153,7 +153,7 @@ href="./html/index.html">doxygenDoc</a></p>
|
||||
<p>The first step is to build pvDatabaseCPP as described in the next section.</p>
|
||||
<p>One of the examples is exampleServer.
|
||||
It can be started either via a main program or as part of a V3 IOC.
|
||||
<p>
|
||||
</p>
|
||||
<p>To start it as a main program do the following:</p>
|
||||
<pre>
|
||||
mrk> pwd
|
||||
@ -270,13 +270,13 @@ It is expected that these threads will be sufficient to efficiently handle all c
|
||||
channelRPC. For channelRPC pvAccess provides (or will provide) a thread pool for channelRPC requests.
|
||||
If, in the future, a scanning facility is provided by pvDatabaseCPP or some other facility,
|
||||
then the scanning facility will have to provide some way of handling process requests that block.</p>
|
||||
</p>
|
||||
<h3>Phased Development</h3>
|
||||
<p>This documentation describes the first phase of a phased implementation of pvDatabaseCPP:</pp>
|
||||
<p>This documentation describes the first phase of a phased implementation
|
||||
of pvDatabaseCPP:</p>
|
||||
<dl>
|
||||
<dt>pvRecord</d>
|
||||
<dt>pvRecord</dt>
|
||||
<dd>Wrapper on PVStructure that implements methods required by Local Channel Provider.</dd>
|
||||
<dt>pvDatabase</d>
|
||||
<dt>pvDatabase</dt>
|
||||
<dd>Database of PVRecords. Has methods find, add, and remove.</dd>
|
||||
<dt>Local Channel Provider</dt>
|
||||
<dd>Complete implementation of ChannelProvider and Channel.
|
||||
@ -294,10 +294,11 @@ then the scanning facility will have to provide some way of handling process req
|
||||
<dd>Add the ability to optionally add support to fields.
|
||||
In addition some of the basic support defined in pvIOCJava could also be implemented.</dd>
|
||||
<dt>XML parser</dt>
|
||||
<dd>This provides the ability to create record instances without writing any code.</dd>
|
||||
<dd>This provides the ability to create record instances without
|
||||
writing any code.</dd>
|
||||
</dl>
|
||||
<p>The completion of each phase provides useful features that can be used without waiting for the
|
||||
completion of later phases.
|
||||
<p>The completion of each phase provides useful features that can be used
|
||||
without waiting for the completion of later phases.
|
||||
The rest of this document discusses only the first phase.</p>
|
||||
<h3>Features Required for localChannelProvider</h3>
|
||||
<dl>
|
||||
@ -314,7 +315,9 @@ The rest of this document discusses only the first phase.</p>
|
||||
<dt>The localChannelProvider itself</dt>
|
||||
<dd>This is the C++ implementation of package pvAccess in pvIOCJava.
|
||||
The localChannelProvider accesses data from PVRecords.
|
||||
It implements all channel methods except channelRPC, which is implemented by pvAccessCPP.</dd>
|
||||
It implements all channel methods except channelRPC,
|
||||
which is implemented by pvAccessCPP.
|
||||
</dd>
|
||||
</dl>
|
||||
<h3>Minimum Features Required for pvRecord</h3>
|
||||
<p>The first phase will only implement record processing, i. e.
|
||||
@ -323,7 +326,8 @@ This will be sufficient for implementing many services.
|
||||
The following are the minimum features required</p>
|
||||
<dl>
|
||||
<dt>PVDatabase</dt>
|
||||
<dd>This holds a set of PVRecords. It has methods to find, add, and remove records.</dd>
|
||||
<dd>This holds a set of PVRecords.
|
||||
It has methods to find, add, and remove records.</dd>
|
||||
<dt>PVRecord</dt>
|
||||
<dd>This, and a set of related interfaces, provides the following:
|
||||
<dl>
|
||||
@ -331,9 +335,11 @@ The following are the minimum features required</p>
|
||||
<dd>PVRecord is a wrapper on a top level pvStructure.</dd>
|
||||
<dt>Record locking</dt>
|
||||
<dd>A record can be locked and unlocked.
|
||||
A record must be locked whenever data in the pvStructure is accessed.</dd>
|
||||
A record must be locked whenever data in the pvStructure is accessed.
|
||||
</dd>
|
||||
<dt>Trapping data changes</dt>
|
||||
<dd>A client can request to be notified when data in the pvStructure is modified.
|
||||
<dd>A client can request to be notified when data in the pvStructure
|
||||
is modified.
|
||||
It can do this on a field by field basis.</dd>
|
||||
</dl>
|
||||
</dd>
|
||||
@ -421,11 +427,11 @@ of how an application can make the shell commands available.
|
||||
<dt>stopPVAClient</dt>
|
||||
<dd>Stops pvAccess.</dd>
|
||||
<dt>startPVAServer</dt>
|
||||
<dd>Starts the local channel provider</p>
|
||||
<dd>Starts the local channel provider</dd>
|
||||
<dt>stopPVAServer</dt>
|
||||
<dd>Stop the local channel provider</dd>
|
||||
</dl>
|
||||
</p>
|
||||
|
||||
<h3>Commands implemented by pvDatabaseCPP</h3>
|
||||
<p>The following iocsh commands are provided for a V3IOC:</p>
|
||||
<dl>
|
||||
@ -433,16 +439,16 @@ of how an application can make the shell commands available.
|
||||
<dd>Provides a list of all the pvRecords in database <b>master</b>
|
||||
</dd>
|
||||
</dl>
|
||||
<p>In addition any code that implements a PVRecord must implement an ioc command.</p>
|
||||
<p>Look at any of the examples to see how to implement shell commands.</p>
|
||||
<p>In addition any code that implements a PVRecord must implement an ioc command.
|
||||
Look at any of the examples to see how to implement shell commands.</p>
|
||||
<h3>Commands implemented by pvaSrv</h3>
|
||||
<p><b>pvaSrv</b> provides a pvAccess server that provides access to iocCore records.</p>
|
||||
<p>pvaSrv does not provide any shell commands but it can be part of an IOC.
|
||||
Just make sure your application configures pvaSrv and then include the following file:
|
||||
</p>
|
||||
<pre>
|
||||
include "dbPv.dbd"
|
||||
</pre>
|
||||
</p>
|
||||
|
||||
<h2>database</h2>
|
||||
<h3>src/database</h3>
|
||||
@ -530,15 +536,12 @@ typedef std::tr1::shared_ptr<PVRecordClient> PVRecordClientPtr;
|
||||
class PVListener;
|
||||
typedef std::tr1::shared_ptr<PVListener> PVListenerPtr;
|
||||
|
||||
class RecordPutRequester;
|
||||
typedef std::tr1::shared_ptr<RecordPutRequester> RecordPutRequesterPtr;
|
||||
|
||||
class PVDatabase;
|
||||
typedef std::tr1::shared_ptr<PVDatabase> PVDatabasePtr;
|
||||
</pre>
|
||||
|
||||
<h3>class PVRecord</h3>
|
||||
<p>NOTES:
|
||||
<p>NOTES:</p>
|
||||
<ul>
|
||||
<li>This section uses the name record instead of "an instance of PVRecord".</li>
|
||||
<li>Most clients will access a record via the local channel provider,
|
||||
@ -549,17 +552,17 @@ typedef std::tr1::shared_ptr<PVDatabase> PVDatabasePtr;
|
||||
Most of the methods are used by the pvAccess code.
|
||||
Service implementers will mostly be interested in methods init and process.
|
||||
These are described first.
|
||||
</li>
|
||||
</ul>
|
||||
<hr>PVRecord Methods</h4>
|
||||
<h4>PVRecord Methods</h4>
|
||||
<pre>
|
||||
class PVRecord
|
||||
public epics::pvData::Requester,
|
||||
public std::tr1::enable_shared_from_this<PVRecord>
|
||||
{
|
||||
public:
|
||||
POINTER_DEFINITIONS(PVRecord);
|
||||
|
||||
virtual bool init() {initPVRecord(); return true;}
|
||||
virtual bool init() ;
|
||||
virtual void start() {}
|
||||
virtual void process() {}
|
||||
virtual void destroy();
|
||||
@ -801,6 +804,7 @@ that holds the data. It has the following methods:
|
||||
<dt>postPut</dt>
|
||||
<dd>This is called by the code that implements the data interface.
|
||||
It is called whenever the put method is called.</dd>
|
||||
</dl>
|
||||
<h3>class PVRecordClient</h3>
|
||||
<pre>
|
||||
class PVRecordClient {
|
||||
@ -816,7 +820,6 @@ class PVRecordClient {
|
||||
<dt>detach</dt>
|
||||
<dd>The record is being removed from the master database,</dd>
|
||||
</dl>
|
||||
</dl>
|
||||
<h3>class PVListener</h3>
|
||||
<pre>
|
||||
class PVListener {
|
||||
@ -866,7 +869,6 @@ public:
|
||||
bool addRecord(PVRecordPtr const & record);
|
||||
epics::pvData::PVStringArrayPtr getRecordNames();
|
||||
bool removeRecord(PVRecordPtr const & record);
|
||||
virtual std::string getRequesterName();
|
||||
private:
|
||||
PVDatabase();
|
||||
};
|
||||
@ -890,8 +892,6 @@ private:
|
||||
<dt>removeRecord</dt>
|
||||
<dd>Remove a record from the database.
|
||||
If the record was not in the database false is returned.</dd>
|
||||
<dt>getRequesterName</dt>
|
||||
<dd>Virtual method of Requester</dd>
|
||||
</dl>
|
||||
<h2>pvAccess</h2>
|
||||
<p>This is code that provides an implementation of channelProvider as
|
||||
@ -930,7 +930,7 @@ While monitoring is active PVCopyMonitor updates the active monitor element when
|
||||
a postPut is issued to any field being monitored.
|
||||
</p>
|
||||
<p>The following two sections provide a few more details about MonitorLocal
|
||||
and PVCopyMonitor.<p>
|
||||
and PVCopyMonitor.</p>
|
||||
<h4>MonitorLocal</h4>
|
||||
<p>MonitorLocal implements the following abstract base classes:</p>
|
||||
<dl>
|
||||
@ -980,7 +980,7 @@ MonitorLocal manages the following:
|
||||
With a lock held it clears the monitorElement queue
|
||||
and allocates an active element.
|
||||
With no lock held calls pvCopyMonitor->startMonitoring(activeElement)
|
||||
<dd>
|
||||
</dd>
|
||||
<dt>stop</dt>
|
||||
<dd>
|
||||
Called by client.
|
||||
@ -1074,7 +1074,7 @@ and one that is used for testing.</p>
|
||||
<h3>traceRecord</h3>
|
||||
<p>This implements a PVRecord that allows a client to set
|
||||
the trace level of a record. It follows the pattern of a channelPutGet
|
||||
record:
|
||||
record:</p>
|
||||
<pre>
|
||||
traceRecord
|
||||
structure argument
|
||||
@ -1105,7 +1105,7 @@ where:
|
||||
<dt>result</dt>
|
||||
<dd>The result of a cannelPutGet request</dd>
|
||||
</dl>
|
||||
<p>testExampleServerMain.cpp has an example of how to create a traceRecord:
|
||||
<p>testExampleServerMain.cpp has an example of how to create a traceRecord:</p>
|
||||
<pre>
|
||||
PVDatabasePtr master = PVDatabase::getMaster();
|
||||
PVRecordPtr pvRecord;
|
||||
@ -1116,12 +1116,12 @@ pvRecord = TraceRecord::create(recordName);
|
||||
result = master->addRecord(pvRecord);
|
||||
if(!result) cout<< "record " << recordName << " not added" << endl;
|
||||
</pre>
|
||||
</p>
|
||||
<h3>recordList</h3>
|
||||
<p>This implements a PVRecord that allows a client to
|
||||
get the names of all the PVRecords in the PVDatabase.
|
||||
It follows the pattern of a channelPutGet
|
||||
record:
|
||||
</p>
|
||||
<pre>
|
||||
traceRecord
|
||||
structure argument
|
||||
@ -1148,17 +1148,18 @@ requires that a record of this type is present and calls it.
|
||||
Thus user code does not have to use a channelGetPut to get the list
|
||||
of record names.</p>
|
||||
<p>testExampleServerMain.cpp has an example of how to create a traceRecord:
|
||||
</p>
|
||||
<pre>
|
||||
recordName = "recordListPGRPC";
|
||||
pvRecord = RecordListRecord::create(recordName);
|
||||
result = master->addRecord(pvRecord);
|
||||
if(!result) cout<< "record " << recordName << " not added" << endl;
|
||||
</pre>
|
||||
</p>
|
||||
|
||||
<h2>exampleServer</h2>
|
||||
<h3>Overview</h3>
|
||||
<p>The example implements a simple service that has a top level pvStructure:
|
||||
</p>
|
||||
<pre>
|
||||
structure
|
||||
structure argument
|
||||
@ -1234,9 +1235,10 @@ where
|
||||
<dt>exampleServerRegister.cpp</dt>
|
||||
<dd>This has the code to start the service via the following iocsh
|
||||
command.
|
||||
</dd>
|
||||
<dt>exampleServerRegister.dbd</dt>
|
||||
<dd>This is the file that is used to create the shell command
|
||||
exampleServerCreateRecord.</dd>
|
||||
exampleServerCreateRecord.
|
||||
<pre>
|
||||
exampleServerCreateRecord exampleServer
|
||||
</pre>
|
||||
@ -1271,7 +1273,7 @@ separate from where the iocs are build.</p>
|
||||
<p>The example resides in src
|
||||
The implementation is in exampleServer.cpp.
|
||||
</p>
|
||||
</p>The description consists of</p>
|
||||
<p>The description consists of</p>
|
||||
<pre>
|
||||
class ExampleServer;
|
||||
typedef std::tr1::shared_ptr<ExampleServer> ExampleServerPtr;
|
||||
@ -1299,30 +1301,31 @@ private:
|
||||
</pre>
|
||||
<p>where</p>
|
||||
<dl>
|
||||
<dt>create<dt>
|
||||
<dt>create</dt>
|
||||
<dd>This is example specific but each support could provide
|
||||
a similar static method.
|
||||
</dd>
|
||||
<dt>~ExampleServer<dt>
|
||||
<dt>~ExampleServer</dt>
|
||||
<dd>The destructor must be declared virtual.</dd>
|
||||
<dt>destroy</dt>
|
||||
<dd>Called when the record is being destroyed.
|
||||
This must call the base class destroy method.
|
||||
<dt>init<dt>
|
||||
</dd>
|
||||
<dt>init</dt>
|
||||
<dd>A method to initialize the support. It returns true
|
||||
if initialization is successful and false if not.
|
||||
NOTE that this is a virtual method of PVRecord itself.</dd>
|
||||
<dt>process<dt>
|
||||
<dt>process</dt>
|
||||
<dd>
|
||||
This again is a virtual method of PVRecord.
|
||||
</dd>
|
||||
<dt>ExampleServer<dt>
|
||||
<dt>ExampleServer</dt>
|
||||
<dd>For the example this is private.</dd>
|
||||
<dt>pvValue</dt>
|
||||
<dd>This is the field of the top level structure that process
|
||||
accesses.
|
||||
</dd>
|
||||
<dl>
|
||||
</dl>
|
||||
<p>The implementation of create method is:</p>
|
||||
<pre>
|
||||
ExampleServerPtr ExampleServer::create(
|
||||
@ -1423,16 +1426,16 @@ int main(int argc,char *argv[])
|
||||
if(!result) cout<< "record " << recordName << " not added" << endl;
|
||||
recordName = "traceRecordPGRPC";
|
||||
pvRecord = TraceRecord::create(recordName);
|
||||
result = master->r;addRecord(pvRecord);
|
||||
result = master->addRecord(pvRecord);
|
||||
if(!result) cout<< "record " << recordName << " not added" << endl;
|
||||
recordName = "recordListPGRPC";
|
||||
pvRecord = RecordListRecord::create(recordName);
|
||||
result = master->r;addRecord(pvRecord);
|
||||
result = master->addRecord(pvRecord);
|
||||
if(!result) cout<< "record " << recordName << " not added" << endl;
|
||||
ServerContext::shared_pointer pvaServer =
|
||||
startPVAServer(PVACCESS_ALL_PROVIDERS,0,true,true);
|
||||
PVStringArrayPtr pvNames = master->r;getRecordNames();
|
||||
shared_vector<const string>r; names = pvNames->r;view();
|
||||
PVStringArrayPtr pvNames = master->getRecordNames();
|
||||
shared_vector<const string> names = pvNames->view();
|
||||
for(size_t i=0; i<names.size(); ++i) cout << names[i] << endl;
|
||||
string str;
|
||||
while(true) {
|
||||
@ -1452,13 +1455,13 @@ This:
|
||||
<li>Runs forever until the user types exit on standard in.</li>
|
||||
</ul>
|
||||
<h3>V3IOC exampleServer</h3>
|
||||
<p>To start exampleServer as part of a V3IOC:
|
||||
<p>To start exampleServer as part of a V3IOC:</p>
|
||||
<pre>
|
||||
mrk> pwd
|
||||
/home/hg/pvDatabaseCPP/exampleServer/iocBoot/exampleServer
|
||||
mrk> ../../../bin/linux-x86_64/exampleServer st.cmd
|
||||
</pre></p>
|
||||
<p>You can then issue the commands dbl and pvdbl:
|
||||
</pre>
|
||||
<p>You can then issue the commands dbl and pvdbl:</p>
|
||||
<pre>
|
||||
epics> dbl
|
||||
pvdouble
|
||||
@ -1472,7 +1475,6 @@ epics>
|
||||
</pre>
|
||||
dbl shows the V3 records.
|
||||
pvdbl shows the pvRecords.
|
||||
</p>
|
||||
<p>
|
||||
It starts pvaSrv so that the V3 records can be accessed via Channel Access
|
||||
or via PVAccess.</p>
|
||||
@ -1516,7 +1518,6 @@ and 2) gives a brief description of an example that gets data for an array of do
|
||||
If access is via pvAccess then locking is handled by pvAccess.</dd>
|
||||
</dl>
|
||||
<p>Access via pvAccess can be done either by local or remote channel provider.</p>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt>Access via channelProviderLocal</dt>
|
||||
<dd>
|
||||
@ -1558,7 +1559,8 @@ i. e. a main program, or can be part of a V3IOC.</p>
|
||||
ClientFactory::start();
|
||||
ChannelProviderLocalPtr channelProvider = getChannelProviderLocal();
|
||||
...
|
||||
ServerContext::shared_pointer serverContext = startPVAServer(PVACCESS_ALL_PROVIDERS,0,true,true);
|
||||
ServerContext::shared_pointer serverContext =
|
||||
startPVAServer(PVACCESS_ALL_PROVIDERS,0,true,true);
|
||||
</pre>
|
||||
<p>The first call is only necessary if some of the pvRecords
|
||||
have pvAccess links.
|
||||
@ -1614,7 +1616,7 @@ exampleLink is a record that, when processed, gets the value from doubleArray an
|
||||
to the value read.
|
||||
st.local has both records.
|
||||
st.remote has only one record named exampleLinkRemote.
|
||||
<p>
|
||||
</p>
|
||||
<p>To start the example:</p>
|
||||
<pre>
|
||||
mrk> pwd
|
||||
@ -1789,7 +1791,7 @@ or some other memory check program.
|
||||
<dd>Remote client that uses channelGet to access the array served by arrayPerformanceMain.</dd>
|
||||
<dt>longArrayPutMain</dt>
|
||||
<dd>Remote client that uses channelPut to access the array served by arrayPerformanceMain.</dd>
|
||||
<dl>
|
||||
</dl>
|
||||
<p>Each has support for <b>-help</b>.</p>
|
||||
<pre>
|
||||
mrk> pwd
|
||||
@ -1797,7 +1799,7 @@ mrk> pwd
|
||||
mrk> bin/linux-x86_64/arrayPerformanceMain -help
|
||||
arrayPerformanceMain recordName size delay providerName nMonitor queueSize waitTime
|
||||
default
|
||||
arrayPerformance arrayPerformance 10000000 0.0001 local 1 2 0.0
|
||||
arrayPerformanceMain arrayPerformance 10000000 0.0001 local 1 2 0.0
|
||||
|
||||
mrk> bin/linux-x86_64/longArrayMonitorMain -help
|
||||
longArrayMonitorMain channelName queueSize waitTime
|
||||
@ -1826,7 +1828,7 @@ bin/linux/<arch>/longArrayGetMain
|
||||
bin/linux/<arch>/longArrayPutMain
|
||||
</pre>
|
||||
<p>Each program generates a report every second when it has something to report.
|
||||
Examples are:
|
||||
Examples are:</p>
|
||||
<pre>
|
||||
mrk> bin/linux-x86_64/arrayPerformanceMain
|
||||
arrayPerformance arrayPerformance 10000000 0.0001 local 1 2 0
|
||||
@ -1889,13 +1891,14 @@ get kiloElements/sec 8726.34
|
||||
</dl>
|
||||
<p>
|
||||
arrayPerformance creates a PVRecord that has the structure:.
|
||||
</p>
|
||||
<pre>
|
||||
recordName
|
||||
long[] value
|
||||
timeStamp timeStamp
|
||||
alarm alarm
|
||||
</pre>
|
||||
Thus it holds an array of 64 bit integers.</p>
|
||||
Thus it holds an array of 64 bit integers.
|
||||
<p>The record has support that consists of a separate thread that runs
|
||||
until the record is destroyed executing the following algorithm:</p>
|
||||
<dl>
|
||||
@ -1984,9 +1987,9 @@ Every second it produces a report.</p>
|
||||
|
||||
<h3>Some results</h3>
|
||||
<h4>array performance</h4>
|
||||
<p>The results were from my laptop.
|
||||
It has a 2.2Ghz intel core i7 with 4Gbytes of memory.
|
||||
The operating system is linux fedora 16.</p>
|
||||
<p>The results were from my laptop in 2013
|
||||
It had a 2.2Ghz intel core i7 with 4Gbytes of memory.
|
||||
The operating system was linux fedora 16.</p>
|
||||
<p>When test are performed with large arrays it is a good idea to also
|
||||
run a system monitor facility and check memory and swap history.
|
||||
If a test configuration causes physical memory to be exhausted
|
||||
@ -2008,7 +2011,7 @@ connection.</p>
|
||||
and is putting about 500million elements per second.
|
||||
Since each element is an int64 this means about 4gigaBytes per second.
|
||||
</p>
|
||||
<p>When no monitors are requested and a remote longArrayMonitorMain is run:<p>
|
||||
<p>When no monitors are requested and a remote longArrayMonitorMain is run:</p>
|
||||
<pre>
|
||||
mr> pwd
|
||||
/home/hg/pvDatabaseCPP-md
|
||||
@ -2075,7 +2078,7 @@ thread1 value 10 time 1.04836 iterations/sec 4.76936 elements/sec 238.468million
|
||||
thread0 value 11 time 1.01575 iterations/sec 4.92249 elements/sec 246.124million
|
||||
</pre>
|
||||
<p>As more threads are running the slower each thread runs.</p>
|
||||
<p>But now consider a size that fits in a local cache.<p>
|
||||
<p>But now consider a size that fits in a local cache.</p>
|
||||
<pre>
|
||||
bin/linux-x86_64/vectorPerformanceMain 5000 0.00n/linux-x86_64/vectorPerformanceMain 5000 0.00 1
|
||||
...
|
||||
|
Reference in New Issue
Block a user