17
Low-latency и soft-realtime на Python Денис Колодин ЗАО «ИК-Форум»

Денис Колодин: Low-latency и soft-realtime на Python

Embed Size (px)

DESCRIPTION

 

Citation preview

Page 1: Денис Колодин: Low-latency и soft-realtime на Python

Low-latency и soft-realtime на Python

Денис КолодинЗАО «ИК-Форум»

Page 2: Денис Колодин: Low-latency и soft-realtime на Python

Что такое latency?

LATENCYвременная задержка между полезной работой

latency

Page 3: Денис Колодин: Low-latency и soft-realtime на Python

Что такое real-time?

REAL-TIMEсистема с известной максимальной latency

(при этом задержкой можно пренебречь)

Page 4: Денис Колодин: Low-latency и soft-realtime на Python

Классификация алгоритмов

CPU-BOUNDСкорость алгоритма зависит линейно от скорости процессора

IO-BOUNDСкорость алгоритма зависит линейно от

скорости ввода-вывода

Page 5: Денис Колодин: Low-latency и soft-realtime на Python

Python и real-time

Ограничения:• Global Interpreter Lock• Невысокая скорость выполнения вычислений• Активное использование malloc• Сборщик мусора

Преимущества:• Простота проектирования• Лёгкое межпроцессное взаимодействие• Отсутствие JIT• Низкоуровневые интерфейсы

Page 6: Денис Колодин: Low-latency и soft-realtime на Python

Как написать real-time код?•Асинхронность– (шаблон Reactor)

• Гранулярность•Управление памятью• Расчёт penalty

•Модули:– threading– multiprocessing– сtypes

•Использование cython

Не заставляйте ваших клиентов ждать!

Page 7: Денис Колодин: Low-latency и soft-realtime на Python

Асинхронность

• Шаблон проектирования Reactor• Используйте волокна вместо потоков• Примеры реализации – Twisted, Tornado

Не занимайте ресурсы

напрасно

Page 8: Денис Колодин: Low-latency и soft-realtime на Python

Асинхронность

from twisted.internet import reactorfrom twisted.internet import task

def routine_1(): print ("Routine 1")

def routine_2(): print ("Routine 2")

t1 = task.LoopingCall(routine_1)t1.start(0)

t2 = task.LoopingCall(routine_2)t2.start(0)

reactor.run( )

Работаетв 2 и 3 :)

Не создаётся конкурирующий контекст потока

Page 9: Денис Колодин: Low-latency и soft-realtime на Python

Гранулярность

• Обработка данных отдельно от подсистемы взаимодействия

• Минимальная подготовка к ответу• Отложенные результаты (deferreds)

Минимизируйте время обмена

данными

Page 10: Денис Колодин: Low-latency и soft-realtime на Python

Гранулярность

from threading import Thread, Lockfrom datetime import datetime

lock = Lock()counter = 0

def worker(tiny): global counter with lock: counter += 1 id = counter r = range(1000000)

if not tiny: yield [id, sum(r)] else: result = [id, None] yield result s = 0 for x in r: s += x if x % 100: yield result[1] = s

Освобождение ресурсов

Ресурсоёмкая работа не должна блокировать

программу

Page 11: Денис Колодин: Low-latency и soft-realtime на Python

Управление памятью

• Выделение памяти создаёт непредсказуемую latency

• Создавайте объекты заранее (пул)• Используйте объекты повторно

(контейнеры)

Выделяйте память заранее

Page 12: Денис Колодин: Low-latency и soft-realtime на Python

Управление памятью

class Stack(object):

def __init__(self, size): self.index = -1 self.storage = [None] * size

def put(self, value): try: self.index += 1 self.storage[self.index] = value except IndexError: self.index -= 1 raise

def pop(self): try: self.index -= 1 result = self.storage[self.index] self.storage[self.index] = None return result except IndexError: self.index += 1 raise

ЭффективностьO(1)

Отказ от выделения памяти сокращает время выполнения

Добавление с поиском

Page 13: Денис Колодин: Low-latency и soft-realtime на Python

Расчёт penalty

• Ставьте паузы в потоках, когда нет задач• Увеличивайте паузу после каждого «отбоя»• Установите лимит ожидания

Предотвращайте пустую работу

Page 14: Денис Колодин: Low-latency и soft-realtime на Python

Управление памятью

from threading import Threadfrom Queue import Queue, Emptyfrom time import sleep

class SmartThread(Thread):

def __init__(self, penalty=0): super(SmartThread, self).__init__() self.daemon = True self.penalty = penalty self.step = penalty / 10 self.sleep = 0 self.queue = Queue()

def run(self, penalty=False): while True: try: d = self.queue.get_nowait() self.wait except Empty: if self.penalty: if self.sleep < self.penalty: self.sleep += self.step sleep(self.sleep)Ожидание в момент простоя

Процессор не греется!

Page 15: Денис Колодин: Low-latency и soft-realtime на Python

Модули

• threading (фоновая работа)• multiprocessing (вычислительная нагрузка)• ctypes (программные интерфейс ОС)

Используйте модули

Page 16: Денис Колодин: Low-latency и soft-realtime на Python

Cython

• Язык для создания Python расширений• Высокая скорость работы кода• Миграция критичных компонент в C

Используйте cython

Page 17: Денис Колодин: Low-latency и soft-realtime на Python

СПАСИБО ЗА ВНИМАНИЕ ;)