Уведомления

Группа в Telegram: @pythonsu

#1 Июнь 26, 2012 09:58:30

Dmitri
Зарегистрирован: 2012-06-26
Сообщения: 5
Репутация: +  0  -
Профиль   Отправить e-mail  

Оптимизация работы с arrays в ctypes

Здравствуйте.
Есть плата обработки цифровых сигналов ‘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 );

И главный вопрос - что делать, чтобы так не делать?

Офлайн

#2 Июнь 26, 2012 12:09:18

Dmitri
Зарегистрирован: 2012-06-26
Сообщения: 5
Репутация: +  0  -
Профиль   Отправить e-mail  

Оптимизация работы с arrays в ctypes

О данных:
Сигнал на плату идет с частотой 1Гц, т.е. 1 из 5 вызовов ‘handleTm’
Пример результата: Tm(clock=2.2130746798892735, shots=52991, 52992, 52993, 52994, 52995)

Отредактировано Dmitri (Июнь 26, 2012 12:09:37)

Офлайн

#3 Июнь 26, 2012 18:57:54

reclosedev
От: Н.Новгород
Зарегистрирован: 2012-03-29
Сообщения: 870
Репутация: +  173  -
Профиль   Отправить e-mail  

Оптимизация работы с arrays в ctypes

Действительно, как-то медленно работают ctypes array, медленнее простого Python списка.

Если я правильно понял, вам не хочется использовать дополнительные специализированные библиотеки с функциями (daskaux.findnextmask)?

Можно попробовать numpy (особенно если он уже есть в зависимостях проекта).

import numpy
 
def makeShots(pmem):
    arr = numpy.frombuffer(pmem, dtype=numpy.uint32)
    return numpy.where(arr & 0x03)[0]
Скорее всего это будет медленнее чем C функция из-за оверхеда на преобразование (это еще проверить нужно), но быстрее ctypes (проверено).

Отредактировано reclosedev (Июнь 26, 2012 19:01:34)

Офлайн

#4 Июнь 26, 2012 22:16:13

Dmitri
Зарегистрирован: 2012-06-26
Сообщения: 5
Репутация: +  0  -
Профиль   Отправить e-mail  

Оптимизация работы с arrays в ctypes

Да, хотелось бы не зарываться в С
Спасибо, проверю, отпишусь.

Офлайн

#5 Июнь 27, 2012 10:24:36

Dmitri
Зарегистрирован: 2012-06-26
Сообщения: 5
Репутация: +  0  -
Профиль   Отправить e-mail  

Оптимизация работы с arrays в ctypes

#(5) ~0.0015s

def makeShots(pmem):
	return list(numpy.where(numpy.frombuffer(pmem, dtype=numpy.uint32) & 0x03)[0])

Вельми гуд, хотя в логах тип numpy.array, а не list.
Ну да ладно, спасибо

Офлайн

#6 Июнь 27, 2012 11:24:25

Dmitri
Зарегистрирован: 2012-06-26
Сообщения: 5
Репутация: +  0  -
Профиль   Отправить e-mail  

Оптимизация работы с arrays в ctypes

def makeShots(pmem):
	return numpy.where(numpy.frombuffer(pmem, dtype=numpy.uint32) & 0x03)[0].tolist()

Отредактировано Dmitri (Июнь 27, 2012 11:24:48)

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version