kirr has uploaded this change for review. (
https://gerrit.osmocom.org/c/osmocom-bb/+/40087?usp=email )
Change subject: trx_toolkit/burst_fwd: Optimize rx_msg.burst -> tx_msg.burst ->
tx_msg.payload by doing it in one go
......................................................................
trx_toolkit/burst_fwd: Optimize rx_msg.burst -> tx_msg.burst -> tx_msg.payload by
doing it in one go
fake_trx receives bursts and create TxMsg objects deserialized from received data.
Then BurstForwarder is asked to forward that TxMsg to recipient transceivers.
What happens on forwaring is:
1) TxMsg is converted to RxMsg. In particular TxMsg.burst is converted
to RxMsg.burst by way of ubit2sbit transformation.
2) then TRX.handle_data_msg -> TRX.send_data_msg -> ... -> Msg._gen_msg ->
RxMsg.append_burst_to
serializes this burst to data to send via sbit2usbit
And all that happens for every incoming burst multiplied by the number
of recepient transceivers.
We can save significant time by doing ubit -> sbit -> usbit
transformation in one go instead of doing ubit -> sbit first, and then
sbit -> usbit as second separate step.
-> Adjust BurstForwarder to do so.
It works by adding custom BurstForwarder-specific private field to RxMsg
and by running added ubit2usbit transformation directly if
RxMsg.append_burst_to sees this field set.
Change-Id: Ie92ec20d0ba6bb3f78db50ddbee33bf9e259cc40
---
M src/target/trx_toolkit/burst_fwd.pyx
M src/target/trx_toolkit/data_msg.pxd
M src/target/trx_toolkit/data_msg.pyx
M src/target/trx_toolkit/test_data_msg.py
4 files changed, 38 insertions(+), 3 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/osmocom-bb refs/changes/87/40087/1
diff --git a/src/target/trx_toolkit/burst_fwd.pyx b/src/target/trx_toolkit/burst_fwd.pyx
index db910ad..10b1b58 100644
--- a/src/target/trx_toolkit/burst_fwd.pyx
+++ b/src/target/trx_toolkit/burst_fwd.pyx
@@ -72,8 +72,8 @@
tx_msg.fn = rx_msg.fn
tx_msg.tn = rx_msg.tn
tx_msg.ver = trx.data_if._hdr_ver
- if rx_msg.burst is not None:
- tx_msg.burst = RxMsg._ubit2sbit(rx_msg.burst)
+ tx_msg.burst = None # skip creating tx_msg.burst - instead do
+ tx_msg._tburst = rx_msg.burst # rx_msg.burst -> tx_msg.payload.burst transformation
in one go
tx_msg.nope_ind = (rx_msg.burst is None)
trx.handle_data_msg(src_trx, rx_msg, tx_msg)
diff --git a/src/target/trx_toolkit/data_msg.pxd b/src/target/trx_toolkit/data_msg.pxd
index 2ddd248..5dd14b9 100644
--- a/src/target/trx_toolkit/data_msg.pxd
+++ b/src/target/trx_toolkit/data_msg.pxd
@@ -48,6 +48,8 @@
cdef void __sbit2ubit(const int8_t *sbits, Py_ssize_t l, uint8_t *ubits) noexcept
@staticmethod
cdef void __ubit2sbit(const uint8_t *ubits, Py_ssize_t l, int8_t *sbits) noexcept
+ @staticmethod
+ cdef void __ubit2usbit(const uint8_t *ubits, Py_ssize_t l, uint8_t *usbits) noexcept
@staticmethod
cdef array.array[int8_t] _usbit2sbit(const uint8_t[::1] usbits)
@@ -57,6 +59,8 @@
cdef array.array[uint8_t] _sbit2ubit(const int8_t[::1] sbits)
@staticmethod
cdef array.array[int8_t] _ubit2sbit(const uint8_t[::1] ubits)
+ @staticmethod
+ cdef array.array[uint8_t] _ubit2usbit(const uint8_t[::1] ubits)
@final
@@ -73,6 +77,7 @@
@no_gc # NOTE by default cython thinks that .burst might participate in cycle
cdef class RxMsg(Msg):
cdef public array.array burst # array.array[b] | None
+ cdef bytearray _tburst # bytearray | None untransformed burst from TxMsg from
BurstForwarder
cdef public int rssi # RSSI_UNSET - unset
cdef public int toa256 # TOA256_UNSET - unset
diff --git a/src/target/trx_toolkit/data_msg.pyx b/src/target/trx_toolkit/data_msg.pyx
index 07b3d38..bdc3119 100644
--- a/src/target/trx_toolkit/data_msg.pyx
+++ b/src/target/trx_toolkit/data_msg.pyx
@@ -194,6 +194,15 @@
Msg.__ubit2sbit(&ubits[0], l, &sbits[0])
return sbits
+ @staticmethod
+ cdef array.array[uint8_t] _ubit2usbit(const uint8_t[::1] ubits): # array[B] ->
array[B]
+ ''' Convert bits {1..0} to unsigned soft-bits {254..0}. '''
+ l = len(ubits)
+ cdef array.array[uint8_t] usbits = array.clone(_Bempty, l, zero=False)
+ Msg.__ubit2usbit(&ubits[0], l, &usbits[0])
+ return usbits
+
+
# inplace versions of Xbit2Ybit
@staticmethod
cdef void __usbit2sbit(const uint8_t *usbits, Py_ssize_t l, int8_t *sbits) noexcept:
@@ -219,6 +228,12 @@
b = ubits[i]
sbits[i] = -127 if b else 127
+ @staticmethod
+ cdef void __ubit2usbit(const uint8_t *ubits, Py_ssize_t l, uint8_t *usbits) noexcept:
+ for i in range(l):
+ b = ubits[i]
+ usbits[i] = 254 if b else 0
+
# for tests (`@staticmethod cpdef` is not supported:
github.com/cython/cython/issues/3327)
@staticmethod
@@ -229,6 +244,8 @@
def sbit2ubit(sbits): return Msg._sbit2ubit(sbits)
@staticmethod
def ubit2sbit(ubits): return Msg._ubit2sbit(ubits)
+ @staticmethod
+ def ubit2usbit(ubits): return Msg._ubit2usbit(ubits)
cdef _validate(self):
@@ -488,6 +505,7 @@
cdef _reset(self):
Msg._reset(self)
self.burst = None
+ self._tburst = None
self.rssi = RSSI_UNSET
self.toa256 = TOA256_UNSET
@@ -749,7 +767,16 @@
''' Generate message specific burst appending it to buf. '''
# Convert soft-bits to unsigned soft-bits
+ #
+ # but if we have burst coming from TxMsg in transformed form, do
+ # TxMsg (bits) -> RxMsg (signed soft-bits) -> unsigned soft-bits in one go
l = PyByteArray_GET_SIZE(buf)
+ if self._tburst is not None:
+ PyByteArray_Resize(buf, l+len(self._tburst))
+ Msg.__ubit2usbit(<uint8_t*>PyByteArray_AS_STRING(self._tburst),
len(self._tburst),
+ <uint8_t*>&PyByteArray_AS_STRING(buf)[l])
+ return
+
if self.burst is None:
return
PyByteArray_Resize(buf, l+len(self.burst))
diff --git a/src/target/trx_toolkit/test_data_msg.py
b/src/target/trx_toolkit/test_data_msg.py
index 8d1d014..8f73e11 100644
--- a/src/target/trx_toolkit/test_data_msg.py
+++ b/src/target/trx_toolkit/test_data_msg.py
@@ -146,13 +146,16 @@
self.assertEqual(usbits[:255], usbits_ref[:255])
self.assertEqual(usbits[255], 254)
- # Test both sbit2ubit() and ubit2sbit()
+ # Test all sbit2ubit(), ubit2sbit() and ubit2usbit()
ubits = Msg.sbit2ubit(sbits_ref)
self.assertEqual(ubits, array('B', [1] * 127 + [0] * 128))
sbits = Msg.ubit2sbit(ubits)
self.assertEqual(sbits, array('b', [-127] * 127 + [127] * 128))
+ usbits = Msg.ubit2usbit(ubits)
+ self.assertEqual(usbits, array('B', [254] * 127 + [0]*128))
+
def _test_transform(self, msg):
# Prepare given messages
msg.rand_hdr()
--
To view, visit
https://gerrit.osmocom.org/c/osmocom-bb/+/40087?usp=email
To unsubscribe, or for help writing mail filters, visit
https://gerrit.osmocom.org/settings?usp=email
Gerrit-MessageType: newchange
Gerrit-Project: osmocom-bb
Gerrit-Branch: master
Gerrit-Change-Id: Ie92ec20d0ba6bb3f78db50ddbee33bf9e259cc40
Gerrit-Change-Number: 40087
Gerrit-PatchSet: 1
Gerrit-Owner: kirr <kirr(a)nexedi.com>
Gerrit-CC: fixeria <vyanitskiy(a)sysmocom.de>
Gerrit-CC: osmith <osmith(a)sysmocom.de>
Gerrit-CC: pespin <pespin(a)sysmocom.de>