summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--dpd/dpd.ini4
-rw-r--r--src/ConfigParser.cpp3
-rw-r--r--src/ConfigParser.h2
-rw-r--r--src/DabMod.cpp6
-rw-r--r--src/DabModulator.cpp7
-rw-r--r--src/DabModulator.h5
-rw-r--r--src/MemlessPoly.cpp29
-rw-r--r--src/MemlessPoly.h3
8 files changed, 41 insertions, 18 deletions
diff --git a/dpd/dpd.ini b/dpd/dpd.ini
index 08564d9..21d7d45 100644
--- a/dpd/dpd.ini
+++ b/dpd/dpd.ini
@@ -24,6 +24,10 @@ enabled=1
enabled=1
polycoeffile=dpdpoly.coef
+# How many threads to use for the predistorter.
+# If not set, detect automatically.
+#num_threads=2
+
[output]
# to prepare a file for the dpd/iq_file_server.py script,
# use output=file
diff --git a/src/ConfigParser.cpp b/src/ConfigParser.cpp
index 459811f..f27eb08 100644
--- a/src/ConfigParser.cpp
+++ b/src/ConfigParser.cpp
@@ -172,6 +172,9 @@ static void parse_configfile(
if (pt.get("poly.enabled", 0) == 1) {
mod_settings.polyCoefFilename =
pt.get<std::string>("poly.polycoeffile", "default");
+
+ mod_settings.polyNumThreads =
+ pt.get<int>("poly.num_threads", 0);
}
// Output options
diff --git a/src/ConfigParser.h b/src/ConfigParser.h
index 22a4fc5..89f0fb7 100644
--- a/src/ConfigParser.h
+++ b/src/ConfigParser.h
@@ -75,7 +75,7 @@ struct mod_settings_t {
std::string filterTapsFilename = "";
std::string polyCoefFilename = "";
-
+ unsigned polyNumThreads = 0;
#if defined(HAVE_OUTPUT_UHD)
OutputUHDConfig outputuhd_conf;
diff --git a/src/DabMod.cpp b/src/DabMod.cpp
index 7c342a2..1f10fb8 100644
--- a/src/DabMod.cpp
+++ b/src/DabMod.cpp
@@ -328,7 +328,8 @@ int launch_modulator(int argc, char* argv[])
mod_settings.normalise,
mod_settings.gainmodeVariance,
mod_settings.filterTapsFilename,
- mod_settings.polyCoefFilename);
+ mod_settings.polyCoefFilename,
+ mod_settings.polyNumThreads);
if (format_converter) {
flowgraph.connect(modulator, format_converter);
@@ -433,7 +434,8 @@ int launch_modulator(int argc, char* argv[])
mod_settings.normalise,
mod_settings.gainmodeVariance,
mod_settings.filterTapsFilename,
- mod_settings.polyCoefFilename);
+ mod_settings.polyCoefFilename,
+ mod_settings.polyNumThreads);
if (format_converter) {
flowgraph.connect(modulator, format_converter);
diff --git a/src/DabModulator.cpp b/src/DabModulator.cpp
index 5282a2d..ccc2085 100644
--- a/src/DabModulator.cpp
+++ b/src/DabModulator.cpp
@@ -63,7 +63,8 @@ DabModulator::DabModulator(
float& digGain, float normalise,
float gainmodeVariance,
const std::string& filterTapsFilename,
- const std::string& polyCoefFilename
+ const std::string& polyCoefFilename,
+ unsigned int polyNumThreads
) :
ModInput(),
myOutputRate(outputRate),
@@ -77,6 +78,7 @@ DabModulator::DabModulator(
myFlowgraph(NULL),
myFilterTapsFilename(filterTapsFilename),
myPolyCoefFilename(polyCoefFilename),
+ myPolyNumThreads(polyNumThreads),
myTiiConfig(tiiConfig)
{
PDEBUG("DabModulator::DabModulator(%u, %u, %u, %zu) @ %p\n",
@@ -222,7 +224,8 @@ int DabModulator::process(Buffer* dataOut)
shared_ptr<MemlessPoly> cifPoly;
if (not myPolyCoefFilename.empty()) {
- cifPoly = make_shared<MemlessPoly>(myPolyCoefFilename);
+ cifPoly = make_shared<MemlessPoly>(
+ myPolyCoefFilename, myPolyNumThreads);
rcs.enrol(cifPoly.get());
}
diff --git a/src/DabModulator.h b/src/DabModulator.h
index 0c691dd..56a6f91 100644
--- a/src/DabModulator.h
+++ b/src/DabModulator.h
@@ -56,7 +56,9 @@ public:
float& digGain, float normalise,
float gainmodeVariance,
const std::string& filterTapsFilename,
- const std::string& polyCoefFilename);
+ const std::string& polyCoefFilename,
+ unsigned int polyNumThreads);
+
DabModulator(const DabModulator& other) = delete;
DabModulator& operator=(const DabModulator& other) = delete;
virtual ~DabModulator();
@@ -82,6 +84,7 @@ protected:
OutputMemory* myOutput;
std::string myFilterTapsFilename;
std::string myPolyCoefFilename;
+ unsigned int myPolyNumThreads;
tii_config_t& myTiiConfig;
size_t myNbSymbols;
diff --git a/src/MemlessPoly.cpp b/src/MemlessPoly.cpp
index 71ceac3..b0d950c 100644
--- a/src/MemlessPoly.cpp
+++ b/src/MemlessPoly.cpp
@@ -53,9 +53,10 @@ static const std::array<complexf, 8> default_coefficients({{
}});
-MemlessPoly::MemlessPoly(const std::string& coefs_file) :
+MemlessPoly::MemlessPoly(const std::string& coefs_file, unsigned int num_threads) :
PipelinedModCodec(),
RemoteControllable("memlesspoly"),
+ m_num_threads(num_threads),
m_coefs(),
m_coefs_file(coefs_file),
m_coefs_mutex()
@@ -63,6 +64,16 @@ MemlessPoly::MemlessPoly(const std::string& coefs_file) :
PDEBUG("MemlessPoly::MemlessPoly(%s) @ %p\n",
coefs_file.c_str(), this);
+ if (m_num_threads == 0) {
+ const unsigned int hw_concurrency = std::thread::hardware_concurrency();
+ etiLog.level(info) << "Polynomial Predistorter will use " <<
+ hw_concurrency << " threads (auto detected)";
+ }
+ else {
+ etiLog.level(info) << "Polynomial Predistorter will use " <<
+ m_num_threads << " threads (set in config file)";
+ }
+
RC_ADD_PARAMETER(ncoefs, "(Read-only) number of coefficients.");
RC_ADD_PARAMETER(coeffile, "Filename containing coefficients. When written to, the new file gets automatically loaded.");
@@ -156,12 +167,15 @@ int MemlessPoly::internal_process(Buffer* const dataIn, Buffer* dataOut)
std::lock_guard<std::mutex> lock(m_coefs_mutex);
const unsigned int hw_concurrency = std::thread::hardware_concurrency();
- if (hw_concurrency) {
- const size_t step = sizeOut / hw_concurrency;
+ const unsigned int num_threads =
+ (m_num_threads > 0) ? m_num_threads : hw_concurrency;
+
+ if (num_threads) {
+ const size_t step = sizeOut / num_threads;
vector<future<void> > flags;
size_t start = 0;
- for (size_t i = 0; i < hw_concurrency - 1; i++) {
+ for (size_t i = 0; i < num_threads - 1; i++) {
flags.push_back(async(launch::async, apply_coeff,
m_coefs, in, start, start + step, out));
@@ -177,13 +191,6 @@ int MemlessPoly::internal_process(Buffer* const dataIn, Buffer* dataOut)
}
}
else {
- static bool error_printed = false;
- if (not error_printed) {
- etiLog.level(warn) <<
- "Your platform doesn't seem to have hardware concurrency. "
- "MemlessPoly will run single-threaded";
- }
- // For some reason we don't have hw concurrency.
apply_coeff(m_coefs, in, 0, sizeOut, out);
}
}
diff --git a/src/MemlessPoly.h b/src/MemlessPoly.h
index 9fe19d7..b7fd81e 100644
--- a/src/MemlessPoly.h
+++ b/src/MemlessPoly.h
@@ -52,7 +52,7 @@ typedef std::complex<float> complexf;
class MemlessPoly : public PipelinedModCodec, public RemoteControllable
{
public:
- MemlessPoly(const std::string& coefs_file);
+ MemlessPoly(const std::string& coefs_file, unsigned int num_threads);
virtual const char* name() { return "MemlessPoly"; }
@@ -67,6 +67,7 @@ private:
int internal_process(Buffer* const dataIn, Buffer* dataOut);
void load_coefficients(const std::string &coefFile);
+ unsigned int m_num_threads;
std::vector<complexf> m_coefs;
std::string m_coefs_file;
mutable std::mutex m_coefs_mutex;