Jump to content

rockcavera

Super VIP
  • Posts

    373
  • Joined

  • Last visited

  • Days Won

    1

Everything posted by rockcavera

  1. Minha postagem sobre a comparação dos métodos fala a partir de qual processador Intel e Amd a instrução está presente. Então, portanto, não é portável. Mas você pode criar um ponteiro que na inicialização do programa defina se chama popcnt ou outra função de contagem se o processador não suportar. Claro que ai se tem o custo de chamada de procedimento. Outra forma é disponibilizar dois executáveis, sendo um para popcnt e outro com outra forma de contagem portável.
  2. Testei deste modo. Qual compilador C++ você usa? Se for clang ou gcc, passe -mpopcnt para o builtin usar popcnt instrução. O seu processador também precisa suportar tal instrução. Leia minha postagem que tem tudo sobre. Os testes que fiz usam ticks de processador, injetando assembly no meio do código para ter menos ruído possível na medição. Se não me engano, eu também digo que quanto mais loops você der, mais próximos vão ser os resultados mesmo com métodos diferentes, devido ao fato do processador habilitar o cache. Uma tabela de consulta de 256 é mais provável que seja carregada no cache mais rápido do processador em loops longos que uma tabela de 65535 (16bits).
  3. Aqui eu trouxe vários métodos e uma comparação deles.
  4. Basta dar um COMB3 = COMB1 AND COMB2, depois contar quantos bits continuam ON, ou seja, marcados como 1 em COMB3. O loop for você vai realizar várias operações para verificar apenas 1 bit por vez. Antes de tudo, é preciso ter um conhecimento básico da lógica de programação. Operadores bit a bit (bitwise) precisam ser dominados para enxergar o seu uso.
  5. Escrevo meus programas em Nim. O que eu faço é utilizar inteiros como combinações. Na mega-sena precisa de um inteiro que caiba 60 bits, então uso um inteiro de 64 bits. Nisso, os bits de 0 a 64 são marcados como 1 ou 0 de acordo com o número da combinação, que para mega-sena sempre serão 6 bits marcados como 1. A verificação é praticamente 2 instruções, um AND e um POPCNT. Para loterias você tem que entender o que todos os operadores bitwise fazem para extrair o melhor do programa. São 4 instruções: AND, OR, XOR e NOT. AND para verificar bits iguais, OR para concatenar combinações, XOR e NOT para inverter. Além disso é bom ter conhecimento de operações de deslocamento SHIFT (RIGHT e LEFT). Além disso, é importante conhecer bem a linguagem e o compilador para extrair o máximo de otimizações. No Delphi se tem o tipo LONG, que é um inteiro de 64 bits. Lotomania não vale a pena, né? São trilhões de combinações... Para mega-sena: 103,738484 milissegundos - comparar uma combinação com todas as 50.063.860 combinações já geradas. 482,397266 milissegundos - gerar as 50.063.860 combinações armazenando-as e compará-las com uma única combinação. 197,240098 milissegundos - gerar as 50.063.860 combinações e a cada nova combinação, sem armazenar, já comparar com uma única combinação. Para quina: 88,364074 milissegundos - comparar uma combinação com todas as 50.063.860 combinações já geradas. 603,023102 milissegundos - gerar as 24.040.016 combinações armazenando-as e compará-las com uma única combinação. 319,673796 milissegundos - gerar as 24.040.016 combinações e a cada nova combinação, sem armazenar, já comparar com uma única combinação. Para a quina eu uso um inteiro de 128 bits (nint128) que eu mesmo desenvolvi a biblioteca para Nim.
  6. Concordo. É o que acontece quando se divide o processamento em threads. Aumenta-se a quantidade de memória para dividir o processamento. Não concordo com isso. A operação bit a bit é a melhor forma de se verificar acertos para loterias, pelo menos para CPU. Com operações bits a bits, você pode comparar a quantidade de bits iguais entre dois INTEIROS com duas instruções. Ou seja, se o processador é 64 bits, até 64 bits você vai usar duas instruções para comparar. Depois de anos de otimizações que receberam os compiladores C, muito difícil ele não gerar o melhor código assembly possível. Mas há casos que é preciso se socorrer ao assembly para se obter o melhor mesmo. Bom, ou você não sabe o que diz ou foi muito infeliz no exemplo sem números reais. Na verdade essa diferença pode até acontecer se levarmos em consideração os processadores Intel atuais que possuem núcleos diferentes. Mas se tratando de núcleos idênticos, um programa que faz uma operação em 10 segundos com um thread, no mínimo - NO MÍNIMO MESMO! - vai fazer essa mesma operação com dois threads em 5 segundos. Mas na vida real nunca cai de fato pela metade, pois pode haver um gargalo de hardware em outra parte, como memória, ssd/hd, transferência de dados... que faz o tempo ficar acima da metade. Quanto mais thread se adiciona, mesmo tendo núcleos ou threads ociosas para realizar o trabalho, sempre pode haver um outro gargalo que impede a diminuição do tempo pelo fator de threads rodando. Para comparar um único resultado com as 3.268.760 de combinações da lotofácil demora 5,944806 milissegundos. Agora, para gerar as 3.268.760 de combinações da lotofácil e comparar um único resultado demora 39,307152 milissegundos. Ou seja, 33,362346 milissegundos para alocar memória para as 3.268.760 de combinações e gerá-las. Para impedir otimizações em tempo de compilação, os parâmetros são passados durante a execução. Exemplo: Digito: brincar.exe 25 15 14 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 25 = v 15 = k 14 = número de acertos que pretendo "1 2 3 4 5 6 7 8 9 10 11 12 13 14 15" = combinação que será verificada contra as 3.268.760 de combinações da lotofácil. Ele vai me retornar a quantidade de combinações que fizeram 14 pontos. Isso impede otimizações de tempo de compilação e torna a comparação mais justa, pois posso mudar os parâmetros. Lembrando que o programa é single thread, ou seja, roda em um único thread. Os números podem variar de acordo com o computador. Aqui é um Intel(R) Core(TM) i7-4810MQ CPU @ 2.80GHz com 16 gb de RAM 1600MHz DDR3, em dual channel. Edit: Estava deitado e lembrei que poderia fazer uma refatoração. Agora, gerando cada combinação das 3.268.760 de combinações da lotofácil e logo em seguida comparando com a combinação que será verificada, sem armazenar as 3.268.760 de combinações, obtenho um tempo de 26,712895 milissegundos. Disso, pode se extrair que 6 milissegundos eram gastos, aproximadamente, para alocação da memória para caber as 3.268.760 de combinações. Dessa abordagem se extrair o melhor desempenho e o uso eficiente de memória, pois não armazena as combinações geradas que já foram testadas.
  7. A hospedagem do lotdrw.tk (Nexus Bytes), que parecia confiável, acabou ficando off sem avisar os usuários (grátis e pagos) em janeiro de 2023. O projeto era um hobbie meu, que pretendia tornar mais profissional, mas a falta de tempo acabou impedindo de progredir a contento. Acredito que no curto prazo eu não volte o projeto. Infelizmente, eu não sei onde está o último backup do site, que havia feito em meados de outubro de 2022. Nesses últimos meses acabei formatando o notebook 2 vezes, pois um HD pifou, comprei um SSD e depois comprei um outro HD. Como nem sempre salvo a pasta de downloads do Windows, onde provavelmente estava o backup de outubro de 2022, acabei perdendo ele. Já procurei nos backups do HD externo e nada. Acabou ficando um backup de dezembro de 2021. Então, perdi vários sistemas que foram enviados. Sim, havia um ou dois usuários ativos enviados os sistemas. Queria pedir desculpas aos dois que estavam fazendo a contribuição e dedicando seu tempo. Sobre o LotDrw System Checker, eu não pretendo disponibilizar o código fonte. Mas vou disponibilizar para download o programa em algum link. Abraço.
  8. A hospedagem do lotdrw.tk (Nexus Bytes), que parecia confiável, acabou ficando off sem avisar os usuários (grátis e pagos) em janeiro de 2023. O projeto era um hobbie meu, que pretendia tornar mais profissional, mas a falta de tempo acabou impedindo de progredir a contento. Acredito que no curto prazo eu não volte o projeto. Infelizmente, eu não sei onde está o último backup do site, que havia feito em meados de outubro de 2022. Nesses últimos meses acabei formatando o notebook 2 vezes, pois um HD pifou, comprei um SSD e depois comprei um outro HD. Como nem sempre salvo a pasta de downloads do Windows, onde provavelmente estava o backup de outubro de 2022, acabei perdendo ele. Já procurei nos backups do HD externo e nada. Acabou ficando um backup de dezembro de 2021. Então, perdi vários sistemas que foram enviados. Sim, havia um ou dois usuários ativos enviados os sistemas. Queria pedir desculpas aos dois que estavam fazendo a contribuição e dedicando seu tempo. Sobre o LotDrw Inverter, eu pretendo disponibilizar no meu GitHub o código fonte e o programa binário. Antes do site ficar off, eu estava trabalhando em melhorias do Inverter, que consegui melhorar o desempenho em 20%. Também estava trabalhando com outro pacote de GUI (Interface gráfica do utilizador) que faltavam algumas coisas para finalizar. Não vou dar um prazo de quando isso vai acontecer, mas preciso vir aqui trazer informações para quem fazia o uso do software. Abraços.
  9. A minha postagem que você mesmo citou tem tudo que você está perguntando. Tem uma descrição do algoritmo, tem links, inclusive para um tópico de alternativa ao ININUGA com download dos softwares... Caso não tenha captado alguma informação, leia novamente.
  10. Quando se usa esses builtins no gcc, tem que passar -mpopcnt ao compilar para ele usar a instrução popcnt. Caso contrário ele usa um hack que não é de instrução única.
  11. @Bruno Cintraaté hj não aprendeu a usar o editor do fórum para colocar código? Só lembrando que já tentei te ensinar umas 2 vezes, inclusive com print. Quando se cola código fora da caixa de código, o código pode ser alterado por um encode de entities html, em linguagens que o recuo importa como escopo pode perder espaço... São vários problemas. Então fica de novo essa dica, quem sabe na próxima. Edit: comentário rabugento? Sim. Mas colar um código dessa forma pode atrasar a vida de alguém que tenta compilar isso e não funciona, devido a falta de cautela de quem não usa dos meios corretos para publicar o código.
  12. Precisando de ajuda, só informar a linguagem que eu tento te ajudar. Abraço
  13. @DixieJoe não é difícil traduzir o código de contagem paralela para outras linguagens, tendo em vista que só usa operações de bit (and), operações de deslocamento (shift right) e operações matemáticas (adição, multiplicação e subtração). Estava tomando café-da-tarde e lembrei que esqueci de botar nas observações sobre a instrução POPCNT. A intel implementou na microarquitetura Nehalem, de 2008. Já a AMD implementou na microarquitetura K10 (Barcelona), de 2007. [1] Não é difícil descobrir se seu processador suporta ou não POPCNT, sendo possível fazer isso em tempo de execução e caso não suporte, basta definir para usar outra forma que seja mais portável, igual a contagem em paralelo. Alguns compiladores C até trazem builtins para você determinar isso em tempo de execução. Caso não tenha, a forma mais simples é consultar o retorno de uma instrução CPUID, que praticamente toda linguagem possui, ou em pacote ou como extensão de linguagem. Vamos lá, para um computador amd64 (ou seja, 64 bits) será possível contar até 64 bits por vez com POPCNT. Então, para 100bits, você terá que usar 2 instruções POPCNT. O mesmo acontece para 80. Agora a forma de quebrar os bits, depende de como está implementado essa linguiça de bits. Por exemplo, em computadores de 32 bits quando se precisa usar 64 bits, você usa dois inteiros de 32 bits para fazer um de 64 bits. Então, para quebrar 64 bits em duas partes de 32 bits basta usar operador AND com uma máscara de bits e deslocamentos. Exemplo o número 9223372043297226750 (precisa de 64 bits). A representação em bits é: 1000000000000000000000000000000101111111111111111111111111111110. A parte superior é representada por esses 32 bits: 10000000000000000000000000000001 A parte inferior por esses: 01111111111111111111111111111110 Exemplo em C : #include <stdio.h> int main() { unsigned long long int a = 9223372043297226750ULL; unsigned long int low = a & 0xFFFFFFFFULL; unsigned long int high = a >> 32; printf("%llu\n", a); printf("Low: %lu\n", low); printf("High: %lu\n", high); return 0; } Exemplo em Nim: let a = 9223372043297226750'u64 lo = uint32(a and 0xFFFFFFFF'u64) hi = uint32(a shr 32) echo a echo "low: ", lo echo "high: ", hi Ambas as implementações irão imprimir: 9223372043297226750 low: 2147483646 high: 2147483649 Claro que cada linguagem tem suas especificidades.
  14. Olá, @Omesmo Eu uso contagem de bits para programas de loteria. É a forma mais rápida para se trabalhar com poucas operações de máquina em loterias, o que torna o programa bem mais rápido. A minha experiência em si não é com C, tendo em vista que hoje em dia não é considerado uma linguagem "moderna", mas, sim, com Nim, que compila para C. Ou seja, no final das contas eu uso C só que com uma camada de abstração de Nim. Vamos lá. Há alguns anos eu fiz 10 implementações de countbits diferentes. Implementação 01: conta os bits por subtração em um loop while. Implementação 02: conta os bits por deslocamento Implementação 03: "Counting bits set, in parallel" (contagem de bits definidos, em paralelo) => https://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetParallel Implementação 04: Conta os bits usando uma tabela de consulta de 8 bits usando um while loop até cobrir todos os bits Implementação 05: Conta os bits usando uma tabela de consulta de 8 bits fazendo a soma aninhada de acordo com a quantidade de bits, sem precisar de um while loop Implementação 06: Conta os bits usando uma tabela de consulta de 8 bits fazendo a soma aninhada de acordo com a quantidade de bits, sem precisar de um while loop (diferença quase nula da implementação anterior) Implementação 07: Conta os bits usando uma tabela de consulta de 16 bits usando um while loop até cobrir todos os bits Implementação 08: Conta os bits usando uma tabela de consulta de 16 bits fazendo a soma aninhada de acordo com a quantidade de bits, sem precisar de um while loop Implementação 09: Conta os bits usando uma tabela de consulta de 16 bits fazendo a soma aninhada de acordo com a quantidade de bits, sem precisar de um while loop (diferença quase nula da implementação anterior) Implementação 10: Conta os bits usando a instrução de processador POPCNT Depois de fazer as implementações, resolvi construir um pequeno benchmark para descobrir qual se saia melhor. Abaixo mostro os resultados: Fazendo uma única operação de contagem: Fazendo 100 operações de contagem: Entendendo os resultados: countbitsXX N V Onde: XX é o número da implementação N é o número que irá contar os bits V é a quantidade de vezes que irá contar os bits de N CpuTime = tempo gasto pela CPU para executar o processo atual em segundos Times = V, ou seja, quantidade de vezes que irá contar os bits SumDeltaT = soma de de ticks de CPU gastos para executar o processo MedDeltaT = média de ticks de CPU gasto para cada execução de contagem (SumDeltaT div Times) MinT = menor ticks de CPU registrado em uma única contagem de bits MaxT = maior ticks de CPU registrado em uma única contagem de bits zOut = resultado, ou seja, quantos bits definidos possui o número N Diante essa análise, pode-se classificar às duas melhores implementações, que são a 10 e a 03. O melhor dessas implementações, que elas são de tempo constante, ou seja, o tempo gasto não muda se tiver mais ou menos bits definidos. Já a implementação 01 e 02 não são de tempo constantes, pois pode ser mais rápida se tiver um único bit definido e mais lerda se tiver 32 bits definidos. Observações: 1) Interessante é do teste que executa mais vezes a mesma contagem. É possível ver que o CPU, de forma inteligente, já começa a usar o cache e executar a tarefa de forma mais rápida se comparar com o benchmark que executa uma única vez a contagem. 2) Os benchmarks não são feitos a frio, pois uso um "aquecimento" de CPU utilizando operações de ponto flutuante por, aproximadamente, 1 segundo antes de começar de fato a medição das operações do benchmark. 3) Meu processador é um mobile, que possui turbo boost. Para realizar os benchmarks eu travo o clock dele na frequência base de 2.8ghz e não deixo ele fazer o turbo boost. 4) As desvantagens de usar tabelas de consultas de 8 bits são de ocupar 256 bytes de memória ram para pré-alocar a tabela. Já a tabela de consulta de 16 bits o número de bytes sobe para 65535 (65KB). Para computadores atuais isso é insignificante. 5) A instrução POPCNT foi implementada pela Intel na microarquitetura Nehalem, de 2008. Já a AMD implementou na microarquitetura K10 (Barcelona), de 2007 [1]
  15. Planilhas do excel? Não sabia que dava para fazer dll para usar no excel. Você me deu uma idéia.
  16. Acredito que tal tabela seja a representação do programa COVER, utilizando Simulated Annealing (Recozimento Simulado), que foi escrito pelos autores mencionados. Caso seja e alguém tenha interesse, o código-fonte pode ser baixado aqui, está escrito em C. Para compilar no Windows, usando mingw64 (gcc), eu fiz esse pequeno patch abaixo, que é um diff: Para aplicar, basta copiar e colar isso para um arquivo "windows.patch", colocar este arquivo no diretório que estão os arquivos do cover.zip, ter o git instalado e aplicar com o comando: git apply windows.patch Já para compilar, você precisa do mingw64 e tê-lo na sua variável de ambiente %PATH%. Depois disso, basta executar o arquivo compile.bat.
  17. Foi o intuito da postagem, tentar incentivar pessoal a aprender alguma linguagem. Eu conheci Nim em 2017. Mas comecei a fazer algo só lá para 2018. Antes eu era um amante de Perl. Tudo que precisava fazer, eu fazia em Perl. Caramba, 1982! Você é antigo, em? hahahahaha
  18. O papo de vocês, o @Omesmoe o chargpt, está muito filosófico. Fico me perguntando quem ficará doido antes hahahahahhaha.
  19. De fato o ChatGPT é algo incrível. No entanto, o seu caso de uso, atualmente, está mais voltado para substituir as buscas do Google que substituir o trabalho de um ser humano. Com certeza o pessoal da OpenAI deve estar recebendo um fluxo enorme de Brs nesses dias, pois vi em diversos lugares saindo reportagem sobre o ChatGPT nessa semana, de jornais em papel até sites. Sobre substituir programadores... Eu fiz alguns testes no começo do ano e final do ano passado. Estava bem longe de fornecer códigos 100% funcionais para linguagens que testei. Olha que eram coisas simples. Porém, ele trouxe um código que, para quem não sabe, pode ser um caminho a seguir. É aquele negócio. Para se programar precisa de lógica de programação, mas será que uma máquina consegue imitar o raciocínio lógico do ser humano? Quando isso acontecer, se acontecer, acredito que será algo muito perigoso. Veja teste de Turing. Outra questão envolvendo o ChatGPT é em relação a direitos autorais, uma vez que ele pode estar fazendo um cópia e cola alterando alguma coisa (aplicando sinônimos). Nos resta esperar pelos próximos capítulos.
  20. Adicionada a modalidade Federal. Para baixar todos os resultados da federal basta digitar: lotcef Federal O download pode ser feito aqui. Só tem binários para Windows. Quem quiser usar fora do Windows vai precisar compilar . Aqueles interessados nas mudanças do código e a simplicidade que foi adicionar a modalidade, vejam aqui o diff.
  21. Descobri que a Federal (Loteria Federal) também possui 18 concursos faltantes. Segue abaixo os concursos faltantes:
  22. Obrigado. O código, de fato, foi escrito já com o intuito de disponibilizar aqui, até por isso utilizei nomes em português e comentários em português, principalmente documentando todas as armadilhas que pude notar. Meu primeiro contato com programação lá pelos anos de 2003 ou 2004 também foi com mIRC Scripting. Abraço.
  23. Como tudo surgiu aqui, não poderia deixar de postar. lotcef - Baixa os resultados das loterias da Caixa Econômica Federal
  24. Como mencionado aqui, trago-lhes o programa e, de bônus, o código-fonte. Sim, trago o código-fonte, pois acho um absurdo existirem sites que cobram para as pessoas terem acesso a isso (pesquise no google). Então, a pessoa que conhece o mínimo de programação poderá se inspirar e ver como obter os resultados de forma fácil, sem precisar pagar por um API. O segundo ponto pelo qual eu trago o código-fonte é uma possível motivação para aprenderem uma linguagem de programação, pois o código todo possui pouco mais de 500 linhas, foi escrito em no máximo 12 horas de dedicação, e não usei nenhum pacote de fora da "biblioteca padrão" da linguagem de programação Nim. A linguagem Nim não é tão conhecida como C, C++, Delphi/Pascal, etc., mas é uma linguagem de programação que te deixa ser produtivo. Claro que nem tudo são flores, mas é a linguagem que eu faço tudo hoje em dia. Já programei em Perl, PHP, Javascript, Delphi/Pascal, C e mIRC Scripting, mas nenhuma delas me trouxe a felicidade que é programar em Nim. Bom, vamos parar de enrolação e vamos ao programa. O lotcef é um programa de linha de comandos para baixar os resultados das loterias da Caixa Econômica Federal (CEF). Todos os dados são retirados do site da CEF. Atualmente as modalidades implementadas são: +Milionária, Dia de Sorte, Dupla Sena, Lotofácil, Lotomania, Mega-Sena, Quina, Super Sete e Timemania. Como usar? Por ser um programa de linha de comandos, você necessita acessar o terminal do seu Sistema Operacional. No Windows você pode usar o powershell ou cmd (prompt de comandos). Caso não saiba como fazer, pesquise no Google. Oh, pai Google, pai de todos os... que querem aprender! Para baixar os resultados de todas as modalidades, em formato CSV, com o concurso, digite: lotcef --csv -c +Milionária "Dia de Sorte" "Dupla Sena" Lotofácil Lotomania Mega-Sena Quina "Super Sete" Timemania Onde faço o download? Está hospedado no github meu. Lá possui binários pré-construídos para Windows. Cadê o código-fonte? Como falei, está hospedado no meu github. Espero que seja útil para alguém. Posfácio Melhorias são planejadas, principalmente para adicionar, de forma semi-automatizada, os concursos faltantes para certas modalidades. Quem se interessar por Nim, acesse o site principal, leia o tutorial básico e brinque no próprio navegador. Espero que isso seja um começo na sua jornada como um programador, caso já não seja. Se quiserem que eu fale mais sobre Nim é só perguntar. Abraços.
×
×
  • Create New...