Düşük Gecikmeli Unix / Linux


11

Düşük gecikme / yüksek frekans programlama işlerinin çoğu (iş özelliklerine göre) unix platformlarında uygulanmış görünmektedir. Teknik özelliklerin çoğunda "düşük gecikmeli linux" deneyimi olan insanlar için özel talepte bulunurlar.

Bunun gerçek zamanlı bir linux işletim sistemi anlamına gelmediğini varsayarsak, insanlar bunun ne anlama gelebileceği konusunda bana yardım edebilir mi? İş parçacıklarına CPU benzeşimi ayarlayabileceğinizi biliyorum, ancak bundan daha fazlasını istediklerini varsayıyorum.

Çekirdek ayarları? (Solarflare gibi üreticilerin çekirdek baypas ağ kartları ürettiğini duysam da)?

İşlemler arasında DMA veya muhtemelen paylaşılan bellek nedir? İnsanlar bana kısa fikirler verebilirlerse google üzerinde araştırma yapabilirim.

(Bu soru muhtemelen Yüksek Frekans Ticaretine aşina olan birini gerektirecektir)


2
Çekirdek ayarı, gerçek zamanlı olmayan bir işletim sistemini olabildiğince gerçek zamanlı hale getirmenin yoludur. İplik sabitlemesi de zorunludur. Bununla ilgili daha fazla bilgiyi bu makalede okuyabilirsiniz: coralblocks.com/index.php/2014/04/…
rdalmeida

Yanıtlar:


26

IB ve Hedge Fund ortamlarında HFT gruplarını destekleyen çok sayıda iş yaptım. Sysadmin görünümünden cevap vereceğim, ancak bunların bazıları bu tür ortamlarda programlama için de geçerlidir.

Bir işverenin genellikle "Düşük Gecikme" desteğine başvurduklarında aradığı birkaç şey vardır. Bunlardan bazıları "ham hız" sorularıdır (ne tür 10g kart satın alacağınızı ve hangi yuvayı takacağınızı biliyor musunuz?), Ancak daha fazlası Yüksek Frekanslı Ticaret ortamının gelenekselden farklı olduğu yollarla ilgilidir. Unix ortamı. Bazı örnekler:

  • Unix geleneksel kaynaklar için bunlardan herhangi aç kalmadan süreçlerin çok sayıda çalışan desteklemek için ayarlanmış, ancak bir HFT ortamda, büyük olasılıkla çalıştırmak istediğiniz için vardır bir bağlam anahtarlama için yükü mutlak minimum uygulama, vb. Klasik küçük bir örnek olarak, bir Intel CPU üzerinde hiper iş parçacığının açılması aynı anda daha fazla işlemin çalışmasına izin verir - ancak her bir işlemin yürütüldüğü hız üzerinde önemli bir performans etkisi vardır. Bir programcı olarak, aynı şekilde, diş çekme ve RPC gibi soyutlamaların maliyetine bakmanız ve daha az temiz olsa da daha monolitik bir çözümün nereye yüklenmeyeceğini bulmanız gerekecektir.

  • TCP / IP tipik olarak bağlantı düşüşlerini önlemek ve mevcut bant genişliğini verimli kullanmak için ayarlanır. Amacınız, daha kısıtlı bir bağlantıdan mümkün olan en yüksek bant genişliğini elde etmek yerine, çok hızlı bir bağlantıdan mümkün olan en düşük gecikmeyi elde etmekse, ağ yığınının ayarını ayarlamak isteyeceksiniz. Programlama açısından, mevcut soket seçeneklerine bakmak isteyecek ve hangilerinin varsayılan olarak bant genişliği ve güvenilirlik için gecikmeyi azaltmaktan daha fazla ayarlandığını anlayacaksınız.

  • Ağ iletişimlerinde olduğu gibi, depolamada olduğu gibi - bir uygulama sorunundan bir depolama performansı sorununu nasıl anlatacağınızı bilmek ve hangi G / Ç kullanım modellerinin programınızın performansına en az müdahale edeceğini öğrenmek istersiniz ( Örneğin, eşzamansız IO kullanmanın karmaşıklığının sizin için ne kadar ödeyebileceğini ve olumsuz tarafların ne olduğunu öğrenin).

  • Son olarak ve daha acı verici: Biz Unix yöneticileri izlediğimiz ortamların durumu hakkında mümkün olduğunca fazla bilgi istiyoruz , bu nedenle SNMP aracıları, Nagios gibi aktif izleme araçları ve sar (1) gibi veri toplama araçlarını çalıştırmayı seviyoruz. Bağlam anahtarlarının kesinlikle en aza indirilmesi ve disk ve ağ IO'sunun sıkı bir şekilde kontrol edilmesi gereken bir ortamda, izleme masrafı ile izlenen kutuların çıplak metal performansı arasında doğru dengeyi bulmalıyız. Benzer şekilde, kodlamayı kolaylaştıran ancak performansınızı maliyetlendiren hangi teknikleri kullanıyorsunuz?

Son olarak, zamanla gelen başka şeyler de var; deneyimle öğrendiğiniz hileler ve detaylar. Ancak bunlar daha uzmanlaşmış (ne zaman epoll kullanacağım? Neden teorik olarak aynı PCIe denetleyicilerine sahip iki HP sunucusu modeli çok farklı performans gösteriyor?) .


1
Teşekkür ederim, programlama yanıtıyla ilgilenmeme rağmen bu çok faydalı ve bilgilendiriciydi.
user997112

5
@ user997112 Bu bir programlama cevabıdır. Eğer öyle görünmüyorsa, o zamana kadar okumaya devam edin :)
Tim Post

15

@Jimwise'dan mükemmel donanım / kurulum ayarlama cevabına ek olarak, "düşük gecikme süresi linux" şunları ifade eder:

  • Determinizm nedenleriyle C ++ (GC devreye girdiğinde sürpriz gecikme yok), düşük seviyeli tesislere (G / Ç, sinyaller) erişim, dil gücü (TMP ve STL'nin tam kullanımı, tip güvenliği).
  • bellekte hızı tercih edin:> 512 Gb RAM yaygındır; veritabanları bellek içi, önbelleğe alınmış ön veya egzotik NoSQL ürünleridir.
  • algoritma seçimi: aklı başında / anlaşılabilir / genişletilebilir, mümkün olduğu kadar hızlı, örneğin bool özellikli nesnelerin dizisi yerine kilitsiz, çoklu bit dizileri.
  • Farklı çekirdeklerdeki işlemler arasında Paylaşılan Bellek gibi işletim sistemi olanaklarının tam kullanımı.
  • güvenli. HFT yazılımı genellikle bir Borsa'da bulunur, bu nedenle kötü amaçlı yazılım olanakları kabul edilemez.

Bu tekniklerin birçoğu oyun geliştirme ile örtüşmektedir, bu da finansal yazılım endüstrisinin yakın zamanda yedekli olan herhangi bir program programcısını (en azından kira borçlarını ödeyene kadar) emmesinin bir nedenidir.

Temel ihtiyaç, güvenlik (hisse senetleri, emtia, fx) fiyatları gibi piyasa verilerinin çok yüksek bant genişlikli bir akışını dinleyebilmek ve daha sonra güvenlik, fiyat temelinde çok hızlı bir alım / satım / hiçbir şey yapma kararı verebilmektir. ve mevcut varlıklar.

Tabii ki, bu da tamamen yanlış gidebilir .


Bu yüzden bit dizileri noktasında ayrıntıya gireceğim . Uzun bir Siparişler listesinde çalışan Yüksek Frekanslı Ticaret sistemimiz olduğunu varsayalım (5k IBM Satın Al, 10k DELL Sat, vb.). Diyelim ki tüm siparişlerin yerine getirilip getirilmediğini hızlı bir şekilde belirlememiz gerekiyor, böylece bir sonraki göreve geçebiliriz. Geleneksel OO programlamasında bu şöyle görünecektir:

class Order {
  bool _isFilled;
  ...
public:
  inline bool isFilled() const { return _isFilled; }
};

std::vector<Order> orders;
bool needToFillMore = std::any_of(orders.begin(), orders.end(), 
  [](const Order & o) { return !o.isFilled(); } );

bu kodun algoritmik karmaşıklığı doğrusal bir tarama olduğu için O (N) olacaktır. Bellek erişimleri açısından performans profiline bakalım: std :: any_of () içindeki döngünün her yinelemesi, satır içi olan o.isFilled () öğesini çağıracak, bu nedenle _isFilled, 1 bayt bellek erişimi olacak (veya mimarinize, derleyici ve derleyici ayarlarına bağlı olarak 4) bir nesnenin toplam 128 bayt olduğunu varsayalım. Yani her 128 baytta 1 bayta erişiyoruz. En kötü durumda olduğu varsayılarak 1 baytı okuduğumuzda, CPU veri önbelleğini kaçırırız. Bu, RAM'den tüm satırı okuyan ( daha fazla bilgi için buraya bakın) RAM'e okuma isteğine neden olacak ve sadece 8 biti okuyacaktır. Bu yüzden bellek erişim profili N ile orantılıdır.

Bunu şununla karşılaştır:

const size_t ELEMS = MAX_ORDERS / sizeof (int);
unsigned int ordersFilled[ELEMS];

bool needToFillMore = std::any_of(ordersFilled, &ordersFilled[ELEMS+1],
   [](int packedFilledOrders) { return !(packedOrders == 0xFFFFFFFF); }

bunun en kötü durumda olduğu varsayıldığında, bellek erişim profili ELEMS'in bir RAM hattının genişliğine bölünmesiyle elde edilir (değişir - çift kanallı veya üç kanallı olabilir, vb.).

Aslında, bellek erişim kalıpları için algoritmaları optimize ediyoruz. Hiçbir RAM miktarı yardımcı olmaz - bu ihtiyaca neden olan CPU veri önbellek boyutu.

Bu yardımcı olur mu?


YouTube'da düşük gecikmeli programlama (HFT için) hakkında mükemmel bir CPPCon konuşması var: https://www.youtube.com/watch?v=NH1Tta7purM


"bool özellikli nesneler dizisi yerine birden çok bit dizisi" bununla ne demek istiyorsun?
user997112

1
Örnekler ve linkler üzerinde durdum.
JBRWilkinson

Bir adım daha ileri gitmek - bir siparişin doldurulup doldurulmadığını belirtmek için tüm bir bayt kullanmak yerine - tek bir bit kullanabilirsiniz. Yani tek bir önbellekte (64 bayt) - 256 siparişin durumunu temsil edebilirsiniz. Yani - daha az özlüyor.
quixver

Ayrıca - doğrusal bellek taramaları yapıyorsanız - donanım önceden doldurucu verilerinizi yüklemek için harika bir iş çıkarır. Belleğe art arda veya uzun adımlarla veya basit bir şeye erişmeniz şartıyla. Ancak belleğe ardışık olmayan herhangi bir şekilde erişiyorsanız - CPU prefetcher karıştırılır. Örneğin, bir ikili arama. Bu noktada programcı cpu'ya ipuçlarıyla yardımcı olabilir - _mm_prefetch.
quixver

-2

Bir ya da iki yüksek frekanslı yazılımı üretmediğim için en önemli şeyleri söyleyebilirim:

  1. Ağ mühendisleri ile birlikte donanım yapılandırması ve sistem yöneticileri, alım satım sistemi tarafından işlenen sipariş sayısının iyi bir sonucunu tanımlamazlar, ancak yukarıda ana hatları verilen temel bilgileri bilmiyorlarsa büyük zamanları düşürebilirler.
  2. Aslında sistemi yüksek frekanslı ticaret yapmak için yapan tek kişi c ++ kodu bir araya koyar bir bilgisayar bilim adamı

    Kullanılan bilgiler arasında

    A. Karşılaştırma ve Değiştirme işlemleri.

    • CAS'ın işlemcide nasıl kullanıldığı ve bilgisayarın Kilitlemesiz yapı işlemede kullanılmasını nasıl desteklediği. Veya Kilitsiz işleme. Burada tam bir kitap yazmayacağım. Kısaca GNU derleyicisi ve Microsoft derleyicisi CAS talimatlarının doğrudan kullanımını destekliyor. Kuyruktan öğe çıkarılırken veya kuyruğa yeni bir kod eklenirken kodunuzun "No.
  3. Yetenekli bilim adamı daha fazlasını kullanacak. Öncelikle Java'da ortaya çıkan yeni "desenlerde" bulması gerekir. DISRUPTOR kalıbı denir. Avrupa'daki LMAX borsası Fold, yüksek frekanslı topluluğa, modern işlemcilerde iş parçacığı tabanlı kullanımın, daya kuyruğu modern cpu önbelleğinin boyutuyla hizalanmamışsa CPU tarafından bellek önbellek sürümünde işlem süresini kaybedeceğini açıkladı = 64

    Bu nedenle, bu okuma için, çoklu iş parçacığı işleminin donanım CPU önbelleğini çakışma çözünürlükleri olmadan doğru şekilde kullanmasına izin veren bir java kodu yaptılar. Ve iyi bilgisayar bilimcisi, bu kalıbın zaten c ++ 'a taşındığını veya kendini taşıdığını bulmalı.

    Bu, herhangi bir yönetici yapılandırmasının ötesinde bir yeterlilik yoludur. Bu, bugün yüksek frekansın gerçek kalbinde.

  4. Bilgisayar bilimi adamı sadece QA insanlarına yardım etmek için bir sürü C ++ kodu yazmamalıdır. Ama aynı zamanda
    • tüccarlar valide kanıtlanmış elde edilen hız yüz
    • kınamak farklı eski teknolojileri kullandı ve iyi sonuçlar üretmediklerini göstermek için kendi kodlarıyla ortaya koydu
    • hos kendi çoklu iş parçacıklı iletişim c ++ kodu kanıtlanmış pupe dayalı / tekrar eski çekirdek kullanmak yerine çekirdek hızı seçin. Size bir örnek vereceğim - modern tcp kütüphanesi ICE. Ve bunu yapan insanlar parlaktır. Ancak öncelikleri birçok dille uyumluluk alanındaydı. Yani. C ++ ile daha iyisini yapabilirsiniz. Bu nedenle, ASYNCHRONOUS select çağrısına dayalı olarak en yüksek performanslı örnekleri arayın. Ve birden fazla tüketici için birden fazla üretici için gitmeyin - HF için değil.
      Ve borunun SADECE gelen iletinin çekirdek bildirimi için kullanıldığını görünce şaşıracaksınız. 64 bitlik mesaj numarasını buraya koyabilirsiniz - ancak içerik için size kilitsiz CAS kuyruğuna gidersiniz. Eşzamansız çekirdek select()çağrısı tarafından tetiklenir .
    • Dahası. İletilerinizin akışını / kuyruğunu yapan iş parçacığınıza c ++ iş parçacığı benzeşimi atama hakkında bilgi edinin. Bu iş parçacığının çekirdek yakınlığı olmalı. Başka hiç kimse aynı CPU çekirdek numarasını kullanmamalıdır.
    • ve bunun gibi.

Gördüğünüz gibi - yüksek frekans GELİŞEN BİR ALAN. Başarılı olmak için sadece bir C ++ programcısı olamazsınız.

Ve başarılı olmayı söylediğimde, WILL için çalışacağınız riskten korunma fonunun, insanların ve işverenlerin bahsettiği sayıların ötesinde yıllık tazminat tur çabalarını tanıyacağını kastediyorum.

Basit yapıcı / yıkıcı SSS zamanları sonsuza kadar gitti. Ve c ++… kendisi, bellek yönetiminden kurtulmak ve sınıflarda büyük derinliğin kalıtımsızlığını zorlamak için yeni derleyicilerle göç etti. Zaman kaybı. Kod yeniden kullanım paradigması değişti. Sadece polimorfta kaç sınıf yaptığınızla ilgili değil. Bu, yeniden kullanabileceğiniz kodun doğrulanmış zaman performansı ile ilgilidir.

Bu yüzden orada öğrenme eğrisine girip girmemek sizin seçiminizdir. Asla dur işaretine çarpmaz.


6
Yazım ve biçimlendirme için biraz çaba harcamak isteyebilirsiniz. Mevcut haliyle, bu yazı zar zor anlaşılabilir.
CodesInChaos

1
10 yıl önceki durumu anlatıyorsunuz. Donanım tabanlı çözümler, C ++'nız ne kadar optimize edilmiş olursa olsun, günümüzde saf C ++ 'dan kolayca daha iyi performans gösterir.
Sjoerd

Donanım tabanlı çözümlerin ne olduğunu bilmek isteyenler için - çoğunlukla kodun hızlı belleğe yakıldığı ve ROM belleğinin yeniden yakılmasıyla değişmeyen FPGA çözümleri. Salt Okunur
alex p

@alexp Neden bahsettiğinizi açıkça bilmiyorsunuz. FPGA "hızlı belleğe yazılan kod" dan farklı bir şeydir.
Sjoerd
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.