Jump to content

fredericopissarra

Membros
  • Content Count

    180
  • Joined

  • Last visited

Everything posted by fredericopissarra

  1. Tentou 'cuda'? Tem os drivers instalados corretamente? Tá usando os drivers da nVidia ou o nouveau? Anyway... se 'nvdec' funcionou, então tá ok
  2. Yep.... verifique, antes com: $ ffmpeg -hwaccels Se o seu ffmpeg suporta cuvid ou nvdec. Mesma coisa com encoders (mas a opção é -encoders) - para ver se h264_nvenc é suportado.
  3. Recentemente topei com uma pegunta interessante… O padrão ISO 9989:1999 (e o de 2001) incorporaram funções para lidar com o “ambiente” de ponto flutuante via protótipos de funções contidas no header fenv.h. Isso, literalmente, torna obsoleto o mecanismo que usava a função matherr() — isso é particularmente verdadeiro para a glibc 2.27 em diante. No mecanismo antigo, se a função matherr() estiver definida em seu programa, todas as exceções ocorridas em ponto flutuante são repassadas para ela, como se fosse um tratador de sinal. Isso não funciona mais assim. Agora, temos que usar fenv.h e suas funções… Eis um exemplo: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 /* Define _GNU_SOURCE para podermos usar as extensões feenableexcept() e fedisableexcept() */ #define _GNU_SOURCE #include <stdio.h> #include <stdlib.h> #include <signal.h> #include <fenv.h> /* declara o tratador de SIGFPE */ static void myFPEhandler(int); int main(void) { double a, b, c; // Lê os valores de stdin. scanf( "%lg %lg", &a, &b ); signal( SIGFPE, myFPEhandler ); // Zera os flags indicadores de exceção. feclearexcept( FE_ALL_EXCEPT ); // Tira a máscara da exceção de divisão por zero. feenableexcept( FE_DIVBYZERO ); c = a / b; printf( "%g / %g = %g\n", a, b, c ); } void myFPEhandler(int sig) { fputs( "Math exception!\n", stderr ); exit( sig + 128 ); } Se, depois de compilarmos, tentarmos fazer: E o troço parece funcionar perfeitamente! Mas, temos um problema: Não é possível testar qual exceção ocorreu! No exemplo acima, retiramos a máscara da exceção de divisão por zero, mas poderíamos “desmascarar” todas as exceções, com feenableexcept(FE_ALL_EXCEPT);. Acontece que a interrupção tratada SIGFPE colocará todas as máscaras no lugar (“re-setadas” ou “setadas de novo”) e limpará os flags indicadores de exceção!!! Se tentarmos criar um tratador como: 1 2 3 4 5 6 7 8 9 10 void myFPEhandler(int sig) { int except = fetestexcept( FE_ALL_EXCEPT ); fprintf( stderr, "Exception %#x ", except ); if ( except & FE_DIVBYZERO ) fputs( "Division by zero!\n", stderr ); else fputs( "Other execption!\n", stderr ); exit( sig + 128 ); } Obteremos: O fato de fetestexcept() retornar 0 mostra o que eu disse antes. Você pode achar que isso é um problema da glibc, mas não é… Tente com o código abaixo: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 #include <stdio.h> #include <stdlib.h> #include <signal.h> #include <x86intrin.h> /* declara o tratador de SIGFPE */ static void myFPEhandler(int); int main(void) { double a, b, c; // Lê os valores de stdin. scanf( "%lg %lg", &a, &b ); signal( SIGFPE, myFPEhandler ); // Tira a máscara da exceção de Divisão por zero. _mm_setcsr( _mm_getcsr() & ~(1 << 9) ); c = a / b; printf( "%g / %g = %g\n", a, b, c ); } void myFPEhandler(int sig) { int except = _mm_getcsr(); fprintf( stderr, "%#x: ", except ); if ( except & 4 ) fputs( "Division by zero!\n", stderr ); fputc( '\n', stderr ); exit( sig + 128 ); } Aqui você obterá: Note que o bit 9 de MXCSR está setado (a máscara de divisão por zero) e os 5 bits inferiores estão zerados (os flags indicadores de exceção)… Aqui estou lidando diretamente com SSE, usando as funções intrínsecas _mm_getcsr() e _mm_setcsr(), que o compilador substituirá pelas instruções STMXCSR e LDMXCSR, respectivamente (sem “chamadas” para a glibc), e a mesmíssima coisa acontece (a palavra de controle MXCSR é reajustada pelo sistema operacional ao chamar o tratador de sinal do processo). Como o kernel “re-seta” as máscaras, elas devem ser desabilitadas de novo dentro do tratador, se você quiser continar tratando as exceções. Isso é simples… mas, o detalhe é que os flags que indicam qual exceção ocorreu também são zerados, antes do tratador ter a chance de obtê-los, e esse problema parece ser incontornável… É possível que exista alguma configuração lá em sys.conf para mudar isso, mas não é prudente fazê-lo. O kernel se comporta dessa maneira para manter o estado do co-processador matemático (80×87) ou SIMD em um padrão coerente (isso está na especificação SysV). Fonte: https://is.gd/TALkiB
  4. A ideia é recodificar um vídeo para ele ficar pequeno e sem perdas de qualidade (ou com a menor perda possível): https://is.gd/FnBQYy https://is.gd/wnOTMK https://is.gd/BHwjlU Yep... no Bit Is Myth.
  5. Eis mais um artiguinho do Bit Is Myth. É uma dica pra quem lida com LaTeX (estou abandonando ambientes como o LibreOffice): https://is.gd/Rx0nOb PS: Sempre tive problemas em importar SVGs no LibreOffice!
  6. Recentemente postei uma pegadinha no Discord: $ cd ~/Temp # Diretório vazio! $ echo TESTE | tr [:upper:] [:lower:] teste As sequências [:upper:] e [:lower:] não são regular expressions, mas atalhos derivados das funções em ctype.h, do C (embora essas "classes" de caracteres existam, também, no padrão estendido POSIX de regexes). Note que a tradução (tr) faz exatamente o que mandamos fazer: Converte caracteres maiúsculos (uppercase) para minúsculos (lowercase). Mas veja isso: $ touch l # cria arquivo 'l', vazio. $ echo TESTE | tr [:upper:] [:lower:] lllll Um amigo topou com isso e eu testei, achando que era algum bug na distro dele... Ué? Mas não é que o troço acontece mesmo? Por quê? O que acontece aqui é que os colchetes '[' e ']' são também usados pelo shell para especificar caracteres, num nome de arquivo. Por exemplo. Se você quiser listar todos os arquivos que comecem com a letra 'L' (maiúsculo e minúsculo), pode fazer algo assim: $ ls [Ll]* Esse '[Ll]*' é expandido pelo shell para todos os nomes de arquivos/diretórios que ele encontrar que atendam ao critério. Assim, [:lower:], sem as aspas, segue o mesmo princípio... Se existirem arquivos de 1 único caracter, cujo nome seja ':', 'l', 'o', 'w', 'e' ou 'r', o shell vai expandir o argumento para todos os arquivos que encontrar. É como se o comando, no exemplo acima, fosse: $ echo TESTE | tr [:upper:] l Se criarmos um arquivo 'r', teremos: $ touch r $ echo TESTE | tr r l r E você obtererá um erro no uso de 'tr' (porque tem um argumento extra que não deveria estar lá). Se apagar o 'l': $ rm l $ echo TESTE | tr [:upper:] [:lower:] # o mesmo que 'tr r r' TESTE O que faltou para evitar essas expansões é colocar os argumentos entre aspas: $ echo TESTE | tr '[:upper:]' '[:lower:]' # Não apaguei 'r'! :) teste Com relação à expansão pelo shell, você pode fazer um teste simples: /* test.c */ #include <stdio.h> int main( int argc, char *argv[] ) { while ( *++argv ) printf( "Arg: \"%s\"\n", *argv ); } Compilando e executando: $ cc -o test test.c $ touch l o w e r # cria os arquivos 'l', 'o', 'w', 'e' e 'r'. $ ./test [:lower:] Arg: "e" Arg: "l" Arg: "o" Arg: "r" Arg: "w" $ ./test '[:lower:]' Arg: "[:lower:]" []s Fred
  7. UAU... Nunca vi isso antes: $ apg Rein8twegdeev~ (Rein-EIGHT-tweg-deev-TILDE) yivBesh2knek| (yiv-Besh-TWO-knek-VERTICAL_BAR) Wild;)slek8 (Wild-SEMICOLON-RIGHT_PARENTHESIS-slek-EIGHT) Didud8Owcees@ (Did-ud-EIGHT-Ow-cees-AT_SIGN) 6OdowCashped` (SIX-Od-ow-Cashp-ed-GRAVE) 2QuewmEftEic\ (TWO-Quewm-Eft-Eic-BACKSLASH)
  8. # ip link eth0 set macaddr xx:xx:xx:xx:xx:xx Se o device aceitar... Obtenha a lista de devices com: # ip link
  9. Acredito que a área "Programação" seja adequada. Basta apenas o povo postar suas dúvidas por lá...
  10. Eis um problema simples que surgiu num forum que sigo... O sujeito queria um jeito de obter o campo do expoente de um double sem usar operadores aritméticos, lógicos, "address-of" e indireção, ou seja, os operadores +, -, *, /, %, &, |, ^ ou ~. Se isso fosse permitido, a solução seria tão simples como: #include <stdint.h> /* Estrutura de um 'double' */ struct double_s { uint64_t f:52; unsigned int e:11; unisgned int s:1; }; int getext( double x ) { struct double_s *p = (struct double_s *)&x; return p->e - 1023; }; Existe uma solução simples, usando uma função da libm, basta a chamada para frexp(). Mas, existe também uma solução matemática. Se você quer descobrir um expoente, use logaritmo: Ou seja: int getext( double x ) { return floor(log2(fabs(x))); } A razão do floor é que o expoente de uma estrutura em ponto flutuante marca o início da janela onde a fração se encontra. Para valores menores que 1 o logaritmo lhe dará valores negativos e precisamos do maior valor menor que x. Já que x pode ser negativo (e não estamos interessados no sinal), obter o seu valor absoluto impede de usarmos valores inválidos para o logaritmo. Ambas as soluções com frexp e log2, são lentas (embora frexp seja a mais rápida delas). De qualquer maneira, é um problema trivial... 😉
  11. Acho pouco provável a existência de computadores quânticos nos próximos 25 anos...
  12. Nos idos do início do século XX acreditavam que teríamos carros voadores... 🙂
  13. Sei... MSBuild e PowerShell agora viraram "código aberto"... tá... ok... Aliás... MSBuild, MS Word e PowerShell... código aberto... a-hã! Tá...
  14. No caso, se alguém acha os manuais da Intel "complicados" de consultar e até mesmo contraditórios em alguns pontos. Os manuais da AMD costumam ser melhores: https://developer.amd.com/resources/developer-guides-manuals/
  15. Pois é... isso meio que detona o "aprendizado com foco nas exigências de mercado", não é? Por que tem tanta gente interessada nessas áreas se a "oportunidade de emprego" é tão baixa? A motivação pode ser o sonho de tornar-se um especialista numa área complexa o suficiente para não haver muita competição... o que é louvável... Mas para tanto, a coisa exige MUITO estudo e sem uma tutela padronizada (aulas fomais, diplomas, títulos), ou seja, o sujeito tende a aprender porque gosta da coisa e quer se destacar. Minha opinião (é claro, só pode ser minha! senão não seria opinião!) é que os "caçadores de emprego" tendem a não aprender coisa alguma, ou não o suficiente para fazer qualquer diferença profissional... Existe uma legião de mediocridade "no mercado" e isso é, justamente, o que eles esperam (pouca oferta [de emprego] para grande demanda [de empregados em potencial]) levam a baixas remunerações e carga de trabalho exasperantes. Veja só as exigências de competência dos candidatos. O sujeito só não precisa saber como construir uma máquina de teletransporte usando chiclete, clip de papel e cuspe...
  16. Hummm... ok, então isso ajuda: Ralf Brown Interrupt List
  17. O problema de usar NASM (ou outro assembler) para criar executáveis é que grande parte das bibliotecas padrão e dos compiladores C geram código bem mais otimizado... É uma questão de trocar o tamanho pela performance e vice-versa.
  18. UNIX Network Programming - The Socket Networking API (W. Richard Stevens)
  19. PS; É claro... se quiser adicionar elementos no final da lista: void addtail( list_T *lstp, void *elemp ) { node_T *p = elemp; // esse será o último elemento! p->next = NULL; if ( ! lstp->tail ) // lista vazia? { lstp->head = lstp->tail = p; return; } // ajusta o nó tail atual para o novo nó. lstp->tail->next = p; lstp->tail = p; }
  20. A turma da OOP acredita que lidar com coisas como polimorfismo é impossível em linguagens "estruturadas". Eis um exemplo de como fazer uma lista de encadeamento simples, em C, com elementos de diversos "tipos"... Considere a palavra-reservada struct: Ela existe para juntar vários tipos em um único container e de forma ordenada. Assim, se definirmos um nó genérico como: typedef struct node_s { struct node_s *next; } node_T; // _T porque _t não deve ser usado! Podemos definir uma estrutura de controle para uma lista como: // Usado para inicializar uma estrutura de lista vazia. #define EMPTY_LIST { NULL, NULL } typedef struct list_s { node_T *head, *tail; } list_T; Podemos agora usar a regra de que todo elemento que será colocado nessa lista deve definir, primeiro, um ponteiro do tipo node_T que aponte para o próximo item da lista... Por exemplo, suponha que eu queira criar uma lista de vetores 3D (x,y,z). Posso definir os elementos como: struct vec3d_element_s { node_T *next; // isso TEM que estar aqui! // nosso vetor: double x, y, z; }; Eis uma rotina que adiciona elementos no início de uma lista: // note que elemp é ponteiro para void, aceita qualquer ponteiro! void addhead( list_T *lstp, void *elemp ) { node_T *p = elemp; p->next = lstp->head; lstp->head = p; // o elemento é a nova 'cabeça' da lista. // Se a lista estiver previamente vazia, temos um novo 'rabo'. if ( ! lstp->tail ) lstp->tail = p; } Note que, junto com a definição da estrutura de lista, defini um macro EMPTY_LIST. Isso permite o seguinte uso: // define uma lista vazia. list_T list = EMPTY_LIST; struct vec3d_element_s *elemp; // ponteiro para nosso novo elemento. elemp = malloc( sizeof *elemp ); // aloca elemento. elemp->x = 0.0; // inicializa dados do elemento. elemp->y = 1.0; elemp->z = sqrt(2.0); // adiciona elemento na lista: addhead( &list, elemp ); Note que nossa lista aceita QUALQUER estrutura que tenha, como seu primeiro membro, um ponteiro para node_T nomeado de next. Poderíamos fazer algo assim: enum vec_type { V2D, V3D, V4D }; struct vec_element_s { node_T *next; enum vec_type vtype; double v[0]; // yep... tamanho 0! }; ... list_T list = EMPTY_LIST; ... // Aloca vetor 2D, inicializa-o e coloca na lista: struct vec_element_s *v2d; v2d = malloc( sizeof *v2d + 2*sizeof( double ) ); v2d->vtype = V2D; v2d->v[0] = 1.0; v2d->v[1] = 2.0; addhead( &list, v2d ); // Aloca vetor 3D, inicializa-o e coloca na lista. struct vec_element_s *v3d; v3d = malloc( sizeof *v3d + 3*sizeof( double ) ); v3d->vtype = V3D; v3d->v[0] = 1.0; v3d->v[1] = 2.0; v3d->v[1] = 3.0; addhead( &list, v2d ); // percorre a lista e faz algo com os elementos: node_T *p; p = list.head; while ( p ) { doSomething( p ); p = p->next; } Na hora de percorrer a lista podemos usar o membro vtype para dedicir o tamanho do array v. Mas, note que a lista não se importa com o tipo do elemento, desde que ele tenha o ponteiro next como primeiro item.
  21. Costumam manter essa página atualizada: https://en.wikipedia.org/wiki/Public_recursive_name_server
×
×
  • Create New...