Есть плата обработки цифровых сигналов ‘ADLINK PCI-7200’ и C API для нее.
Результат чтения платой сигнала выдается в виде функции-прерывания.
На скрипт возлагается забача обработки результата.
class Dask: lib = ctypes.WinDLL('pci-dask.dll') card = None # идентификатор платы size = 100000 # размер буффера чтения pmem = (ctypes.c_uint32 * 100000)() # буффер чтения rate = 500000.0 # опорная частота tm = None # структура синхронизации времени class Clock( object ): def __init__( self, clock=None ): if clock: self.clock = clock else: self.clock = time.clock() def elapsed( self, clock=None ): if clock: return clock - self.clock return time.clock() - self.clock Tm = collections.namedtuple('Tm', 'clock shots') def handleTm(): clock = time.clock() err = resultCast(Dask.lib.DI_AsyncDblBufferTransfer(Dask.card, ctypes.byref(Dask.pmem))) if err == 0: pmem = Dask.pmem clk = Clock() shots = makeShots(pmem) # !!! print u'elapsed> makeShots: {elapsed}'.format(elapsed=clk.elapsed()) if shots: Dask.tm = Tm(clock, shots)
# (1) ~ 0.09 s
def makeShots( pmem ): ret = [] for i in xrange(len(pmem)): if pmem[i] & 0x03: # 1й канал чтение/запись ret.append(i) return ret
# (2) ~ 0.12 s
class Filter( object ): def __init__( self, pmem ): self.pmem = pmem def __call__( self, index ): return self.pmem[index] & 0x03 def makeShots_( pmem ): return filter(Filter(pmem), xrange(len(pmem)))
# (3) ~ 0.09 s
def makeShots__( pmem ): return [i for i in xrange(len(pmem)) if pmem[i] & 0x03]
Итого: 500000/100000 = 5 * ~0.1 = ~ 0.5s/1.0s
# (4) < 0.001 s
def makeShots___( pmem ): beg = 0 end = len(pmem) ret = [] while beg < end: beg = daskaux.findnextmask(ctypes.byref(pmem), beg, end, 0x03) if beg < end: ret.append(beg) beg += 1 return ret
где daskaux.findnextmask - C функция
int findnextmask( U32* data, int beg, int end, U32 mask );
И главный вопрос - что делать, чтобы так не делать?