Cambridge, Reino Unido 23 de junho de 2017 Argon Design uma empresa de serviços de design especializada em sistemas digitais complexos anunciou hoje que desenvolveu um sistema de negociação financeira de ultra baixa latência para uma casa de negociação proprietária fazendo arbitragem de latência em uma das principais bolsas nas Américas. Plataforma de negociação completa que inclui funções de dados de mercado em tempo real ingestão através de suporte de algoritmo para FIX-based colocação de ordem foi ao vivo em maio de 2017 Ele constrói sobre os resultados inovadores Argon anunciou em setembro de 2017 para negociação de alto desempenho usando um design híbrido de FPGA e x86 tecnologias Isso combina caminhos rápidos implementados em FPGA para dar respostas de nível de nanossegundo de tick-to-trade para eventos-chave, juntamente com a configuração de oportunidade, determinação de parâmetros e gerenciamento de sistema em um servidor x86 de alto desempenho. O melhor do hardware de raça compreende um servidor Supermicro Hyper-Speed Com Dual Intel Xeon E5 processadores montados e fornecidos pela Bios IT, bem como um Arista 7124FX Switch com integrado Stratix V FPGA. A lógica FPGA usa uma série de técnicas de otimização desenvolvidas por Argon para maximizar a vantagem de velocidade. Estes incluem in-line parsing, preempção, inferência e arbitragem de gateway Para alimentar as várias técnicas de inferência, o FPGA inclui complexo Lógica para construir e manter livros de pedidos e estatísticas FAST FIX parsing é feito em no máximo 64ns, e construção de livro de ordem é concluída em 32ns Para as interfaces de rede de menor latência, o sistema usa Tamba Networks terminal latência 1G MAC. Casa comentou Como as trocas tornam-se mais determinista, é importante ter uma plataforma que dá uma vantagem de velocidade, bem como estratégias de negociação inteligente O sistema de Argônio deu-nos que edge. Steve Barlow, CTO de Argon Design comentou Troca de alto desempenho continua a ser ativo Através dos mercados mundiais Como se torna indiscutivelmente mais nicho, para ganhar terá de ter acesso às tecnologias de alto desempenho e as habilidades para sele Ct e montar as peças necessárias Em Argon acreditamos no detalhe da engenharia especializada cada cliente é diferente e, portanto, desenvolvemos sistemas sob medida que dão a borda vital. Sobre Argon Design. Argon Design foi fundada em 2009 e opera no coração do mundo O Cluster de Tecnologia de Cambridge, com acesso aos mercados, lidera o intelecto. No setor de negociação financeira, a Argon Design auxilia equipes internas fornecendo habilidades especializadas ou recursos adicionais para projetos, bem como projetos completos feitos sob medida em áreas como hardware heterogêneo e sistema de software Arquitetura. Projeto de design e produção. Programação de desenvolvimento baseada em FPGA. Muitos núcleos de hardware de processador e design de software usando Tilera, Intel e outrosprocessamento de processamento. GPU programação de desenvolvimento e OpenCL. BarsMonster Eu poderia ver embora para coisas como pilhas de rede, que são completamente dependentes da plataforma, seria necessário algum conhecimento antes de ser capaz de mudar de plataformas Plus coisas como garfo que são comuns no mundo POSIX, mas não são possíveis em um ambiente Windows, eu acho que Sa resposta razoável Billy ONeal ago 29 10 at 0 55.Linux UNIX são muito mais utilizável para usuários remotos concorrentes, tornando mais fácil para o script em torno dos sistemas, use ferramentas padrão como grep sed awk perl ruby menos logs ssh scp tudo o que as coisas s Apenas there. There também são questões técnicas, por exemplo, para medir o tempo decorrido no Windows você pode escolher entre um conjunto de funções com base no relógio do Windows tick, eo hardware baseado QueryPerformanceCounter O primeiro é incrementos cada 10 a 16 milissegundos nota documentação alguns Implica mais precisão - por exemplo, os valores de GetSystemTimeAsFileTime medida para 100ns, mas eles relatam o mesmo 100ns borda do relógio tick até que ele tiquetaques novamente O último - QueryPerformanceCounter - tem problemas show-stopping onde diferentes núcleos cpus pode relatar relógios desde inicialização que diferem por vários segundos devido a ser aquecido em diferentes momentos durante a inicialização do sistema MSDN documenta isso como um possível BIOS bug, mas é comum Então, Que quer desenvolver sistemas de negociação de baixa latência em uma plataforma que não pode ser instrumentado corretamente Existem soluções, mas você não vai encontrar qualquer software queridos sentar convenientemente no impulso ou ACE. Many Linux variantes UNIX têm lotes de parâmetros facilmente tweakable para trocar Latência para um evento único contra a latência média sob carga, tamanhos de fatia de tempo, políticas de agendamento, etc Em sistemas operacionais de código aberto, há também a garantia que vem com ser capaz de se referir ao código quando você acha que algo deve ser mais rápido do que é, E o conhecimento de que uma comunidade potencialmente enorme de pessoas foram e estão fazendo tão criticamente - com o Windows é, obviamente, principalmente, vai ser as pessoas que re atribuído a olhar para it. O N o lado da reputação FUD - um pouco intangível, mas uma parte importante das razões para a seleção OS - Acho que a maioria dos programadores na indústria iria apenas confiar Linux UNIX mais para fornecer agendamento confiável e comportamento Além disso, Linux UNIX tem uma reputação de falhar menos, embora Windows é bastante confiável nos dias de hoje, e Linux tem uma base de código muito mais volátil do que o Solaris ou FreeBSD. answered 29 de agosto de 10 em 0 42.Windows sistemas operacionais cliente só permitem que uma pessoa use RDP de cada vez No entanto Windows Terminal Server tem sido em torno Para sempre foi, de fato, o uso original do RDP e permite tantas conexões quanto você tem Licenças de Acesso para Cliente Os SOs do Windows Server vêm com a capacidade de ter mais de um usuário remoto por padrão Se você poderia fonte o comentário sobre agendamento então eu Eu aqui - que parte da resposta parece ser FUD neste momento para mim o resto da resposta é boa YMMV Billy ONeal ago 29 10 em 0 50.There não é UNIX Linux agendamento É um dos Áreas em que as implementações diferem E Linux, de fato, teve mais de uma opção scheduler google Completamente Feira Scheduler Linux para o fundo, assim você pode t mesmo dizer programação Linux é confiável MSalters 30 de agosto 10 a 11 37.I segundo as opiniões de histórico e acesso Para a manipulação do kernel. Além dessas razões eu também acredito que, assim como como eles desligam a coleta de lixo eo mecanismo semelhante em Java ao usar essas tecnologias em alguma latência baixa Eles podem evitar o Windows por causa da API s de alto nível que interagem com Os de baixo nível e, em seguida, o kernel. So o núcleo é, naturalmente, o kernel que pode ser interagido com o uso do baixo nível os As APIs de alto nível são fornecidos apenas para tornar a vida comum dos usuários mais fácil Mas em caso de baixa latência isso se torna Ser uma camada de gordura e perda de fração de segundos em torno de cada operação Então, uma opção lucrativa para ganhar poucos segundos fração por chamada. Outra coisa a considerar é a integração A maioria dos se Rvers, centros de dados, trocas usam UNIX não janelas para usar os clientes da mesma família torna a integração e comunicação mais fácil. Then você tem problemas de segurança muitas pessoas lá fora não podem concordar com este ponto embora hacking UNIX não é fácil em comparação com o corte de WINDOWS I Don t concordar com o licenciamento deve ser a questão para os bancos, porque eles duche de dinheiro em cada peça de hardware e software e as pessoas que personalizá-los, para comprar licenças não será tão maior o problema quando considerado o que ganham por purchase. answered 21 de dezembro 12 at 20 05.Your Answer.2017 Stack Exchange, Inc. Ultra baixa latência Trading Systems. Lazy inicialização para o StringBuilder Alguns allocs até buffer atinge max tamanho necessário. Melhor opção onde a memória é limitada e pode haver muitas instâncias. Não thread seguro Mas isso é FINE como todo o código assumido single threaded a menos que especificado de outra forma. Em ultra baixa latência threading modelo é explícito e toda contenção minimizada e understand. D membro presized var Iable. private final StringBuilder info novo StringBuilder 1024.private Mensagem read. Message m decode. append, isDup. Ok assim que os guardas deviam estar em todos os exemplos, mas no típico código java seu ignorado e as alocações e mempcy pagaram um imposto preguiçoso. Abordagem de baixa latência para o StringBuilder A alocação de buffer único presized a exigência máxima. Não segmento seguro, mas isso é FINE como todo o código assumido single threaded a menos que especificado de outra forma. In modelo de latência ultra baixa latência é explícito e toda a contenção minimizada e entendida. FYI SubMicroTrading doesnt use StringBuilder, mas ReusableString para evitar a sobrecarga de toString e usa byte em vez de char. Não há verdadeira mística em chamadas JNI, o conceito de que JNI é lento é um misnomer Se você manter suas interfaces JNI simples, em seguida, quando o código é compilado o seu apenas um outro Chamada de função allbeit com um extra de dois parâmetros. Eu recomendo envolver chamadas JNI dentro de um envelope que pode permitir alternar entre linux, janelas e talvez não Personalizado JNI Eu desenvolvi SubMicroTrading em um pequeno laptop Dell Adamo e poderia executar o sim de troca, dados de mercado sim, a aplicação de negociação todos em dual core com 4GB RAM tente fazer isso em C. In SubMicroTrading todas as chamadas personalizadas JNI excluindo NIO personalizado são envolvidos dentro de um Classe chamada NativeHooksImpl simplificado e reduzido versão below. public classe NativeHooksImpl implementa NativeHooks. private estático boolean linuxNative false. private estático NativeHooks instância novo NativeHooksImpl. public estático NativeHooks instance. private estática nativa jniSetPriority int mask, int priority. Substituir public void setPriority Thread thread, int mask, int priority. jniSetPriority mask, priority. To gerar o cabeçalho file. javah - force - classpath bin - o src SubMicroCorejni h. Sample entrada do cabeçalho gerado Claramente a função real deve corresponder à definição. JNIEXPORT void JNICALL JavacomrrcoreosNativeHooksImpljniSetPriority JNIEnv, jclass, jint, jint. Implementation para o método de prioridade definido Note que isso define o cpumask ea prioridade para o segmento CURRENT Invocar este método no início do método de execução de thread SubMicroTrading mantém todos os mapeamentos de thread e prioridade em Um arquivo de configuração que é essencial Eu uso diferentes configs para cada servidor de PC diferente. JNIEXPORT void JNICALL JavacomrrcoreosNativeHooksImpljniSetPriority JNIEnv env, jclass clazz, jint cpumask, jint priority. For um sistema para operar o mais rápido possível cada linha de código precisa ser ideal Se Você toma a abordagem de escrever código preguiçoso, em seguida, otimizando você vai acabar reescrevendo tudo Um perfil ganhou T ajudá-lo no nível nanossegundo, a sobrecarga de execução com métricas profiler terá você perseguindo a cauda. Escrever o código ideal desde o início do projeto é fácil, configurar padrões de codificação e aplicá-los Ter um conjunto simples de diretrizes que todo mundo segue. A palavra-chave sincronizada costumava ser muito lento e foi evitado com classes de bloqueio mais complexas usadas em preferência Mas com o advento de sob a tampa de bloqueio de fiação este não é mais o caso Que disse, mesmo se o bloqueio não foi contendido você ainda tem a sobrecarga de Uma barreira de memória de leitura e escrita Então use sincronizado onde é absolutamente necessário, ou seja, onde você tem real concurrency. Key aqui é o projeto de aplicativo onde você quer componentes para ser único threaded e atingir a taxa de transferência através de instâncias concorrentes que são independentes e não requerem sincronização. Minimize o uso de Variáveis voláteis. Entender como seus blocos de construção funcionam, por exemplo, AtomicInteger, ConcurrentHashMap. Only usar técnicas concorrentes para o código que precisa t O ser concurrent. Minimize o uso de operações CAS. Uma operação atômica eficiente ignorando OS e implementado por CPU instrução No entanto, para torná-lo atômico e consistente irá incorrer uma barreira de memória atingindo a eficácia de cache Assim, usá-lo onde necessário e não onde não. Evitar copiar objetos desnecessariamente. Eu vejo isso muito e a sobrecarga pode montar em breve Same é verdadeira para mempcy ing buffer para buffer entre as camadas de API especialmente no código de soquete. Pode ser uma dor para os testes de unidade, mas a questão real vem de simultaneidade necessária de estado compartilhado entre instâncias Funcionando em threads separados. Eu tenho trabalhado em vários sistemas C e java onde, em vez de um modelo de objeto real, eles usaram conceitos abstratos com valores de objeto armazenados em mapas não só estes sistemas funcionam lentamente, mas falta segurança de tempo de compilação e são simples Dor Use mapas onde eles são necessários, por exemplo, um mapa de livros ou um mapa de ordens SMT tem um objetivo de no máximo uma pesquisa de mapa para cada evento. Entender o custo de crescer coleções, por exemplo, um HashMa P tem que criar nova matriz dupla o tamanho, em seguida, rehash seus elementos, uma operação cara quando o mapa está crescendo em centenas de milhares Make tamanho inicial configurable. At final do dia escrever o tamanho de todas as coleções Próxima vez processo é saltado redimensionar para Anterior armazenado máximo Gerar outras métricas como o número de ordens criadas, a percentagem de acerto, a taxa de taxação máxima por segundo figuras que podem ser usadas para compreender o desempenho e dar contexto a latência inesperada. Use Object Orientation. Avoiding orientação do objeto devido ao medo do custo de vtable Lookups parece errado para mim eu posso entendê-lo em uma escala micro, mas em uma macro ponta a ponta escala o que é o impacto Em java todos os métodos são virtuais, mas o compilador JIT sabe quais classes estão atualmente carregados e não só pode evitar uma consulta vtable Mas também pode inline o código O benefício da orientação do objeto é enorme reutilização de componentes e extensibilidade torná-lo fácil de estender e criar novas estratégias sem partes de cortar e colar code. Use Final keyword everywhere. Help o compilador JIT otimizar Se no futuro um método ou classe precisa se estender, então você sempre pode remover a palavra-chave final. Keep métodos pequenos e fáceis de entender Big grandes métodos nunca serão compilados, grandes métodos complexos podem ser compilados, mas O compilador pode terminar de recompilar e recompilar o método para tentar e otimizar David Straker escreveu KISS na placa e eu nunca esqueci Se o código é fácil de entender que s GOOD. Avoid Auto Boxing. Stick para primitivos e uso longo longo Long e Assim evitar qualquer encaixotamento automático encaixotar o auto aviso de boxe em. Os objetos imutáveis são bons para objetos de longa duração, mas pode causar GC para qualquer outra coisa por exemplo, um sistema comercial com dados de mercado teria GC cada segundo se cada carrapato cria um POJO. String imutável É imutável e é um grande não-não para sistemas de latência ultra baixa Em SMT eu tenho um ZString imutável string-like interface Com ViewString e ReusableString implementações concretas. Utilizar byte e byte e evitar tran Slation entre byte e char em cada operação de IO. Nos 80 s eu lembro de construir NAND circuitos para representar código Foi muito legal ver como o código poderia ser implementado em um nível de circuito O que eu estava inseguro de quando eu comecei SubMicroTrading foi o impacto sobre o desempenho Pelo código de byte java e se havia qualquer possível otimizações disponíveis. Para cortar uma longa história curta, eu encontrei apenas uma otimização vale a pena e que s como uma instrução switch é representada em byte code. Consider o seguinte switch statement. case 10 doAStuff break. Caso 20 doBStuff break. case 30 doCStuff break. case 40 doDStuff break. is conceitualmente o mesmo que. if um 10 doAStuff. else se um 20 doBStuff. else se um 30 doCStuff. else se um 40 doDStuff. Think sobre isso, se você São parsing correção e você tem 1000 possíveis correção tags e uma média de 20 campos em uma mensagem Então, para processar uma correção mensagem que você poderia possivelmente estar fazendo uma média de 10.000 comparações Se você quiser processar 1.000.000 eventos por segundo, que woul D ser 10.000.000.000 comparações por segundo Um grande número que seria baseado em pesquisa linear de cima para baixo, a pesquisa binária é claramente muito melhor, mas o ponto é seu ainda um custo que pode ser avoided. Java tem dois bytecodes para as instruções switch, a instrução LookUpSwitch está em Efetuar uma tabela de valor chave para saltar rótulo ou seja, você tem que pesquisar a tabela para encontrar entrada de chave correta TableSwitch é, na verdade, uma tabela de rótulos de salto que são indexados diretamente pelo valor da chave menos o deslocamento da tabela Ie mais baixo valor chave na instrução switch. Para Ultra Baixa Latência você deve considerar adicionar uma tarefa formiga e verificar o bytecode para quaisquer instruções lookupswitch Para o processamento de mensagens na maioria das trocas você pode com segurança forçar uma instrução switch para se tornar um tableswitch, adicionando entradas packer para que não haja lacunas entre os valores chave In Meus geradores de CODEC estipulam um intervalo máximo do bloco por exemplo 100, e todos os valores escassos são segurados dentro da indicação do defeito por exemplo através de uma segunda opção ou da indicação se somente um par chaves De interesse Como tudo testar com dados reais para ver o impacto Para mim, o tableswitch fez enorme diferença. Amostra tablewitch com instruções case packering. Here é o início da instrução switch dentro da classe gerada Standard44Decoder. Não há JVM arg que se encaixa todos Aplicações, a chave é ter uma cama de teste completo repetível e executar benchmarks de escala cheia durante horas não segundos Enxaguar e repetir várias vezes para cada mudança de arg Os args que focalizo são aqueles em SubMicroTrading que não executa nenhum GC e quase não tem aquecimento JIT pós. Por favor, note que algumas dessas bandeiras estão agora em opção desculpe eu não verificado, ainda vale a pena trazê-los à atenção Eu acho. Para aplicações de java padrão que fazem lotes de GC com principalmente objetos de curta duração, eu recomendo tentar o coletor G1 para dados de mercado Eu achei que era muito melhor do que a marca concorrente sweep Eu vou blog sobre isso outro tempo gasto semanas tuning mal concebidos apps conselhos não se incomodam comprar Zing. Note cada atualização Java traz nova op Discute o benchmark de Generics e explique como no PC era diferente de Linux. Evite BiasedLocks eles incorrem em latência regular de milissegundos em sistemas I Em vez de regurgitar o que eu anteriormente googled na compreensão de saída de PrintCompilation. For latência ultra baixa você não quer GC e não JIT, por isso em SMT eu preallocate piscinas e executar o código de aquecimento, em seguida, invocar tomo nota da última compilação, em seguida, Re-running bench test testado olhar para nova saída JIT geralmente recompilação Quando isso ocorre eu voltar para o código de aquecimento e descobrir por que o código de aquecimento tinha que ser recompilado Isso geralmente se resume a qualquer código não está sendo aquecido, ou a rotina Era muito complicado para o compilador Ou adicionar mais código de aquecimento ou simplificar a rotina Adicionando final em todos os lugares realmente helps. Writing código de aquecimento é uma dor, e eu estou eviscerado o met Hod não está implementado ou, pelo menos, não estava em Open JDK1 6 método vazio doh Idealmente, eu iria invocar isso quando o aplicativo está quente e não têm recompilação devido ao compilador pensando que pode fazer mais otimizations. Java pode recompilar e recompilar isso só acontece em Minha experiência quando o método é muito complexo Ofcause se uma recompilação é devido porque java inlined um método não final ea otimização foi prematura, em seguida, o código precisa ser corrigido O que eu quero evitar recompilation otimizações de casos de borda que infrequentemente ir para o código branches. Note Você não pode garantir nenhum GC e nenhum JIT sob qualquer situação em um sistema complexo O que você pode fazer é garantir nenhum JIT GC para KEY cenários especificados que a demanda de negócios Se um sistema de negociação faz 10 milhões de comércios por dia, eu iria definir uma meta de não GC JIT em condições NORMAL com 30 milhões de comércios, em seguida, verificar o desempenho até 100 milhões de ver em que ponto jitter ocorre Se, por exemplo, a troca desconectar você durante o da Y, e que chuta em alguns milisegundos de JIT não é importante Você não precisa de piscina todos os objetos apenas os principais que causam GC Mais sobre isso no futuro blog sobre SuperPools. I lembrar-se de falar com Gil Tene de Azul, enquanto trabalhava em Morgan Stanley e realmente tentou atravessar o quanto mais JIT é de uma dor de GC Alguns desenvolvimentos emocionantes parecem ter sido feitas com Zing e eu teria sido muito interessado em benchtesting que, infelizmente, eu não tenho tempo no presente Muito impressionado com Azul E Gil e como eles respondem a consultas e melhorar o seu produto muito melhor do que a Sun Oracle foram com Java. SubMicroTrading JVM Argumentos.
No comments:
Post a Comment