μHAL (v2.8.17)
Part of the IPbus software repository
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
tools.cpp
Go to the documentation of this file.
1/*
2---------------------------------------------------------------------------
3
4 This file is part of uHAL.
5
6 uHAL is a hardware access library and programming framework
7 originally developed for upgrades of the Level-1 trigger of the CMS
8 experiment at CERN.
9
10 uHAL is free software: you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation, either version 3 of the License, or
13 (at your option) any later version.
14
15 uHAL is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with uHAL. If not, see <http://www.gnu.org/licenses/>.
22
23 Marc Magrans de Abril, CERN
24 email: marc.magrans.de.abril <AT> cern.ch
25
26 Andrew Rose, Imperial College, London
27 email: awr01 <AT> imperial.ac.uk
28
29 Tom Williams, Rutherford Appleton Laboratory, Oxfordshire
30 email: tom.williams <AT> cern.ch
31
32---------------------------------------------------------------------------
33*/
34
35#include "uhal/tests/tools.hpp"
36
37
38#include <chrono>
39#include <fcntl.h>
40#include <vector>
41
42#include "uhal/ProtocolPCIe.hpp"
44
45
46namespace uhal {
47namespace tests {
48
49
51 mHw(aHw),
52 mHwThread([aHw] () {aHw->run();})
53{
54}
55
57{
58 mHw->stop();
59 mHwThread.join();
60}
61
62void DummyHardwareRunner::setReplyDelay(const std::chrono::microseconds& aDelay)
63{
64 mHw->setReplyDelay(aDelay);
65}
66
67
68double measureReadLatency(ClientInterface& aClient, uint32_t aBaseAddr, uint32_t aDepth, size_t aNrIterations, bool aDispatchEachIteration, bool aVerbose)
69{
70 return measureReadLatency(std::vector<ClientInterface*>(1, &aClient), aBaseAddr, aDepth, aNrIterations, aDispatchEachIteration, aVerbose);
71}
72
73
74double measureReadLatency(const std::vector<ClientInterface*>& aClients, uint32_t aBaseAddr, uint32_t aDepth, size_t aNrIterations, bool aDispatchEachIteration, bool aVerbose)
75{
76 Timer myTimer;
77
78 for ( unsigned i = 0; i < aNrIterations ; ++i )
79 {
80 if ( aVerbose )
81 {
82 std::cout << "Iteration " << i << std::endl;
83 }
84
85 for (const auto& c: aClients)
86 c->readBlock ( aBaseAddr, aDepth, defs::NON_INCREMENTAL );
87
88 if ( aDispatchEachIteration )
89 {
90 for (const auto& c: aClients)
91 c->dispatch();
92 }
93 }
94
95 if ( !aDispatchEachIteration )
96 {
97 for (const auto& c: aClients)
98 c->dispatch();
99 }
100
101 return myTimer.elapsedSeconds();
102}
103
104
105double measureWriteLatency(ClientInterface& aClient, uint32_t aBaseAddr, uint32_t aDepth, size_t aNrIterations, bool aDispatchEachIteration, bool aVerbose)
106{
107 return measureWriteLatency(std::vector<ClientInterface*>(1, &aClient), aBaseAddr, aDepth, aNrIterations, aDispatchEachIteration, aVerbose);
108}
109
110
111double measureWriteLatency(const std::vector<ClientInterface*>& aClients, uint32_t aBaseAddr, uint32_t aDepth, size_t aNrIterations, bool aDispatchEachIteration, bool aVerbose)
112{
113 // Send buffer - lots of "cafebabe" (in little-endian)
114 std::vector<uint32_t> sendBuffer ( aDepth, 0xbebafeca );
115 Timer myTimer;
116
117 for ( unsigned i = 0; i < aNrIterations ; ++i )
118 {
119 if ( aVerbose )
120 {
121 std::cout << "Iteration " << i << std::endl;
122 }
123
124 // Create the packet
125 for (const auto& c: aClients)
126 c->writeBlock ( aBaseAddr, sendBuffer, defs::NON_INCREMENTAL );
127
128 if ( aDispatchEachIteration )
129 {
130 for (const auto& c: aClients)
131 c->dispatch();
132 }
133 }
134
135 if ( !aDispatchEachIteration )
136 {
137 for (const auto& c: aClients)
138 c->dispatch();
139 }
140
141 return myTimer.elapsedSeconds();
142}
143
144
145double measureFileReadLatency(const std::string& aFilePath, uint32_t aBaseAddr, uint32_t aDepth, size_t aNrIterations, bool aVerbose)
146{
147 PCIe::File lFile(aFilePath, O_RDWR | O_NONBLOCK);
148 lFile.open();
149
150 std::vector<uint32_t> lRecvBuffer;
151 lFile.read(aBaseAddr, aDepth, lRecvBuffer);
152 lRecvBuffer.clear();
153
154 Timer myTimer;
155 for ( unsigned i = 0; i < aNrIterations ; ++i )
156 {
157 if ( aVerbose )
158 {
159 std::cout << "Iteration " << i << std::endl;
160 }
161
162 lFile.read(aBaseAddr, aDepth, lRecvBuffer);
163 lRecvBuffer.clear();
164 }
165
166 return myTimer.elapsedSeconds();
167}
168
169
170double measureFileWriteLatency(const std::string& aFilePath, uint32_t aBaseAddr, uint32_t aDepth, size_t aNrIterations, bool aVerbose)
171{
172 PCIe::File lFile(aFilePath, O_RDWR);
173 std::vector<uint32_t> lSendBuffer(aDepth, 0x0);
174 lFile.write(aBaseAddr, lSendBuffer);
175
176 Timer myTimer;
177 for ( unsigned i = 0; i < aNrIterations ; ++i )
178 {
179 if ( aVerbose )
180 {
181 std::cout << "Iteration " << i << std::endl;
182 }
183
184 lFile.write(aBaseAddr, lSendBuffer);
185 }
186
187 return myTimer.elapsedSeconds();
188}
189
190
191} // end ns tests
192} // end ns uhal
An abstract base class for defining the interface to the various IPbus clients as well as providing t...
ValHeader writeBlock(const uint32_t &aAddr, const std::vector< uint32_t > &aValues, const defs::BlockReadWriteMode &aMode=defs::INCREMENTAL)
Write a block of data to a block of registers or a block-write port.
void dispatch()
Method to dispatch all queued transactions, and wait until all corresponding responses have been rece...
ValVector< uint32_t > readBlock(const uint32_t &aAddr, const uint32_t &aSize, const defs::BlockReadWriteMode &aMode=defs::INCREMENTAL)
Read a block of unsigned data from a block of registers or a block-read port.
void write(const uint32_t aAddr, const std::vector< uint32_t > &aValues)
void read(const uint32_t aAddr, const uint32_t aNrWords, std::vector< uint32_t > &aValues)
Common abstract base class for IPbus 1.3 and 2.0 dummy hardware.
virtual void run()=0
Function which "starts" the dummy hardware; does not return until the 'stop' method is called.
void setReplyDelay(const std::chrono::microseconds &aDelay)
Definition: tools.cpp:62
DummyHardwareRunner(DummyHardwareInterface *aHw)
Definition: tools.cpp:50
std::unique_ptr< DummyHardwareInterface > mHw
Definition: tools.hpp:67
A very simple timer.
Definition: tools.hpp:74
double elapsedSeconds()
Returns number of elapsed seconds since the timer was instantiated.
Definition: tools.hpp:83
None tests(nox.Session session)
Definition: noxfile.py:19
double measureFileWriteLatency(const std::string &aFilePath, uint32_t aBaseAddr, uint32_t aDepth, size_t aNrIterations, bool aVerbose)
Definition: tools.cpp:170
ClientInterface * c
double measureReadLatency(ClientInterface &aClient, uint32_t aBaseAddr, uint32_t aDepth, size_t aNrIterations, bool aDispatchEachIteration, bool aVerbose)
Definition: tools.cpp:68
double measureFileReadLatency(const std::string &aFilePath, uint32_t aBaseAddr, uint32_t aDepth, size_t aNrIterations, bool aVerbose)
Definition: tools.cpp:145
double measureWriteLatency(ClientInterface &aClient, uint32_t aBaseAddr, uint32_t aDepth, size_t aNrIterations, bool aDispatchEachIteration, bool aVerbose)
Definition: tools.cpp:105