AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / coding / 问题

All perguntas(coding)

Martin Hope
smilingbuddha
Asked: 2025-03-09 10:04:21 +0800 CST

Usando sintaxe de varredura inclusiva no OpenMP na linguagem C

  • 10

Quero usar a operação de varredura inclusiva no OpenMP para implementar um algoritmo. O que se segue é uma descrição da minha tentativa de fazer isso, e não conseguindo mais do que uma aceleração morna.

A operação inclusiva é definida como segue: para um vetor de entrada, digamos que [x1,x2,x3,x4]ele produz a sequência de somas parciais [x1, x1+x2, x1+x2+x3, x1+x2+x3+x4]. Esta é uma operação altamente paralelizável e aparentemente foi bem implementada no OpenMP.

Dei uma olhada na seguinte referência: https://theartofhpc.com/pcse/omp-reduction.html#Scanprefixoperations (A referência do manual https://www.openmp.org/spec-html/5.0/openmpsu45.html#x68-1940002.9.6 parece muito enigmática para mim agora)

O site artofhpc diz que a cláusula de redução recebe um modificador inscan:

#pragma omp parallel for reduction(inscan,+:sumvar)`

No corpo do loop paralelo há uma diretiva scan que permite que você armazene os resultados parciais. Para scans inclusivos, a variável reduction é atualizada antes do pragma scan:

  sumvar // update
#pragma omp scan inclusive(sumvar)
  partials[i] = sumvar

Tentei seguir a mesma sintaxe, para medir o desempenho versus redução serial padrão e os resultados foram bem decepcionantes. Meu código está no final do post.

No código, estou apenas fazendo um teste simples considerando um vetor muito grande de tamanho 90 milhões consistindo de valores aleatórios no intervalo [-1,1], e realizando uma varredura nele usando um número crescente de threads e medindo a aceleração. Aqui estão meus resultados (recebo a mesma resposta em execuções repetidas). A CPU do meu laptop tem 16 threads de hardware, mas a aceleração geral é decepcionante 1,36. (Eu esperaria algo substancialmente maior!)

Há algo errado na maneira como estou usando a sintaxe OpenMP para redução?

➜  Desktop gcc -fopenmp scantest.c  && ./a.out

NumThreads  Speedup
1        0.458
2        1.173
3        1.424
4        1.686
5        1.635
6        1.501
7        1.522
8        1.499
9        1.455
10       1.416
11       1.395
12       1.393
13       1.352
14       1.336
15       1.353
16       1.357
#include<stdio.h>
#include<omp.h>
#include<math.h>
#include<stdlib.h>
#include<assert.h>

int main(int argc, char** argv){

  int N = 9e7;     // vector size 
  double* x;                   // vector to reduce
  double* partials_s;          // vector to scan into
  double* partials_p;          // vector to scan into
  
  double end, start;           // timing variables
  double sumvar;
  
  int tmax = argc>1? atoi(argv[1]):35;
  int threadcount ;

  // Allocate space for all vectors
  x           = (double*) malloc(sizeof(double)*N);
  partials_s  = (double*) malloc(sizeof(double)*N);
  partials_p  = (double*) malloc(sizeof(double)*N);
    
  // Populate the input vectors
  for(int i=0 ; i<N ; ++i){
    x[i] = -1+2.0*rand()/(double)RAND_MAX;
    partials_s[i] = 0.0;
    partials_p[i] = 0.0;
  }

  //-----------------------------------------
  // Serial inclusive scan
  //-----------------------------------------
  start = omp_get_wtime(); 
  sumvar = 0.0;
  for(int i=0 ; i<N ; ++i){
      sumvar += x[i];
      partials_s[i] = sumvar;
  }
  end = omp_get_wtime();
  double stime = end-start; // Time to run the serial code


  //-----------------------------------------------------------------------------
  // Performance of parallel inclusive scan. Print ratio of serial/parallel time
  //----------------------------------------------------------------------------
  printf("\nNumThreads  Speedup \n");
  for(threadcount=1;threadcount<=tmax;++threadcount){

    start = omp_get_wtime();

    sumvar = 0.0;
    #pragma omp parallel for num_threads(threadcount) reduction(inscan,+:sumvar)
    for(int i=0 ; i<N ; ++i){

      sumvar = sumvar + x[i]; // updating the value of sumvar
      #pragma omp scan inclusive(sumvar)
      partials_p[i] = sumvar;
    }
    end = omp_get_wtime();
    double ptime = end-start;

    printf("%d \t %.3f\n",threadcount,stime/ptime);

  }

  //for(int i=0 ; i<N ; ++i){
  //  printf("%.4f  %.4f\n", partials_s[i], partials_p[i]);
  //}

  // Deallocate
  free(x);
  free(partials_s);
  free(partials_p);
  
  return 0;
}
c
  • 3 respostas
  • 69 Views
Martin Hope
Jorge
Asked: 2025-03-09 00:33:11 +0800 CST

Por que em C posso inicializar mais valores do que o tamanho de um array?

  • 10

Este array tem um tamanho de 1, mas eu posso inicializá-lo com esses valores, então eu posso até mesmo definir mais valores depois de instanciar o array e ele ainda funciona. Eu não entendo o porquê.

int array[1] = {12,2,12,12,12,31};

printf("%d\n",array[1]);
printf("%d\n",array[0]);

array[1] = 1;
array[8] = 3;
printf("%d\n",array[1]);// 1 It works. Why?
printf("%d\n",array[8]);// 3 It works. Why?
arrays
  • 3 respostas
  • 145 Views
Martin Hope
lovestacksflow
Asked: 2025-03-08 09:09:35 +0800 CST

Comparando os valores de um certo número de linhas anteriores com a linha atual

  • 10

Em um banco de dados contendo valores de classe de empresa e patente, quero calcular as seguintes variáveis:

Abandono tecnológico: Número de classes de patentes tecnológicas anteriormente ativas abandonadas anualmente.

Especificamente, quero criar variáveis ​​que calculem o número de classes de patentes (variável = classe) que a empresa usou nos últimos 3 anos (t-3, t-2 e t-1) (a observação mínima de um ano anterior é aceitável se o histórico inicial da empresa não tiver 3 anos), mas que estão faltando neste ano (t). Gostaria de fazer o mesmo com uma janela de 5 anos também.

Tenho um conjunto de dados contendo milhões de linhas, então uma solução rápida de data.table é muito preferível.

No seguinte conjunto de dados:

df <- data.table(year=c(1979,1979,1980,1980,1981,1981,1982,1983,1983,1984,1984),
                 category = c("A","A","B","C","A","D","F","F","C","A","B"))

O resultado desejado seria (para uma janela de três anos):

    year        class tech_aband_3
 1: 1979        A     0
 2: 1979        A     0
 3: 1980        B     1
 4: 1980        C     1
 5: 1981        A     2
 6: 1981        D     2
 7: 1982        F     4
 8: 1983        F     3
 9: 1983        C     3
10: 1984        A     3
11: 1984        B     3

No final, terei que executar a solução pelo ID da empresa.

Muito obrigado antecipadamente.

  • 3 respostas
  • 162 Views
Martin Hope
DBS4261
Asked: 2025-03-08 07:59:28 +0800 CST

Crie uma variante de uma matriz cujos elementos são transformados em tipos

  • 10

Eu me deparei com um desafio estranho ao tentar definir um tipo com base em uma matriz enquanto escrevia um código de vinculação de biblioteca.

Considere uma enumeração como a seguinte:

enum class MyTypes
{
    UInt,
    Int,
    Float
}

Com algumas características de tipo, posso converter um valor da enumeração em um tipo:

template <MyTypes Ty> struct typeify;
template <> struct typeify<MyTypes::UInt> { using type = unsigned int; };
template <> struct typeify<MyTypes::Int> { using type = int; };
template <> struct typeify<MyTypes::Float> { using type = float; };
template <MyTypes Ty> using typeify_t = typename typeify<Ty>::type;

Para ajudar com a vinculação, também tenho isso (porque C++ não tem reflexão):

inline static constexpr std::array KnownTypes 
{ 
    std::pair{"UInt", MyTypes::UInt},
    std::pair{"Int", MyTypes::Int},
    std::pair{"Float", MyTypes::Float}
};

A partir daqui, quero definir um std::variantcom base nos meus tipos conhecidos.

Com 3 valores, o óbvio é escrever a variante assim:

std::variant<unsigned int, int, float>

Mas, na minha situação, tenho mais de 50 tipos. Então, eu gostaria de uma maneira de gerar automaticamente a definição de tipo para o std::variantfrom the array of KnownTypese o typeify_ttype trait.

Acho que cheguei perto com o seguinte, mas fiquei bloqueado por não conseguir dar um valor padrão a um parâmetro de modelo variádico:

template <template <typename T, T ... Idx> class temp = std::make_index_sequence<KnownTypes.size()>>
using AnyKnownType = std::variant<typeify_t<KnownTypes[Idx].second>, ...>;
c++
  • 3 respostas
  • 96 Views
Martin Hope
joachim
Asked: 2025-03-07 22:53:46 +0800 CST

Como invocar um callable armazenado dentro de uma propriedade estática?

  • 10

Suponha que eu tenha um chamável estático como \Foo::bar.

Posso atribuir isso a uma variável como esta e então chamá-la:

$myCallable = \Foo::class . '::bar';
// This works.
$myCallable('calling this works!');

Mas se eu atribuir isso a uma propriedade de classe estática como esta:

class MyClass {

  function myFunc() {
    static::$myCallable = \Foo::class . '::bar';

    static::$myCallable('this does not work');
  }

}

falha, porque tenta chamar MyClass::Foo::bar().

Existe alguma maneira de corrigir isso, além de usar call_user_func()?

  • 2 respostas
  • 37 Views
Martin Hope
hanshenrik
Asked: 2025-03-07 07:07:37 +0800 CST

Como deduzir automaticamente o tamanho, mas ser explícito sobre o tipo de std::array?

  • 10

Como você faz o compilador deduzir automaticamente o tamanho e, ao mesmo tempo, ser explícito sobre o tipo em um std::array?

por Como você deduz o tamanho de um std::array? a partir do C++17 você pode deduzir automaticamente ambos com

    std::array a{1, 2, 3};

sendo equivalente a

    std::array<int, 3> a{1, 2, 3};

mas eu quero ser explícito sobre o tipo, mas não o tamanho, eu essencialmente quero

std::array<uint64_t> a{1, 2, 3};

mas essa sintaxe exata resulta em

prog.cc:15:20: error: wrong number of template arguments (1, should be 2)
   15 | std::array<uint64_t> a{1, 2, 3};
      |                    ^
c++
  • 2 respostas
  • 140 Views
Martin Hope
Eric Wang
Asked: 2025-03-06 02:40:45 +0800 CST

Como analisar uma estrutura aninhada apresentada como uma lista simples?

  • 10

Para entender facilmente meu problema, abaixo está uma versão simplificada de alguns exemplos de entrada.

['foo', 1, 'a', 'foo', 2, 'foo', 1, 'b', 'foo', -1, 'foo', -1, "bar", 1, "c", "bar", 2, 'baz', 1, 'd', 'baz', -1, "bar", 3, "e", "bar", 4, 'qux', 1, 'stu', 1, 'f', 'stu', -1, 'qux', -1, 'bar', -1]

(Usei "stu" porque fiquei sem nomes de espaço reservado.)

As strings são nomes de funções (mais ou menos, detalhes depois). Os números depois dos nomes de funções especificam a posição do argumento na função que se segue. Uma posição de -1 fecha a função.

Por exemplo, ['foo',1,'a','foo',2,'b','foo',-1]deve ser equivalente a foo('a', 'b').

Isso também deve funcionar quando aninhado:

['foo', 1, 'a', 'foo', 2, 'foo', 1, 'b', 'foo', -1, 'foo', -1]

deve ser equivalente a foo('a', foo('b'))e

['bar', 1, 'c', 'bar', 2, 'baz', 1, 'd', 'baz', -1, 'bar', 3, 'e', 'bar', 4, 'qux', 1, 'stu', 1, 'f', 'stu',-1, 'qux', -1, 'bar', -1]

deve ser equivalente a bar('c', baz('d'), e, qux(stu('f'))).

Minha função desejada deve retornar uma lista. Por exemplo,

['foo', 1, 'a', 'foo', 2, 'foo', 1, 'b', 'foo', -1, 'foo', -1, 'bar', 1, 'c', 'bar', -1]

deve resultar em

[['foo', 'a', ['foo', 'b']], ['bar', 'c']]

Agora que o problema está mais claro, meu problema real é um pouco diferente. Todos os elementos da lista são inteiros. Os nomes das funções não são strings, são sequências de três inteiros. Portanto, ['foo',1,'a','foo',2,'b','foo',-1]é na verdade [1, 1, 1, 1, 104, 1, 1, 1, 2, 105, 1, 1, 1, -1].

Os nomes das funções ( [1, 1, 1]no exemplo acima) agem como chaves de dicionário. O dicionário (chamado constructs) se parece com isto:

constructs = {
    1: {
        1: {
            1: lambda *chars : print(''.join(chr(char) for char in chars))
        }
    }
}

Então, finalmente, o exemplo deve resultar em algo como

[[lambda *chars : print(''.join(chr(char) for char in chars)), 104, 105]]

Todas as especificações sobre aninhamento e coisas assim ainda devem ser aplicadas. Não tenho ideia de como implementar isso de forma confiável e elegante, por favor ajude!

Desde já, obrigado.

Editar: esqueci de dizer que isso 0é sempre ignorado e pulado, e uma 0chamada de função a seguir escapará da chamada de função e fará com que ela seja tratada como um argumento. Toda essa funcionalidade é implementada até certo ponto na minha tentativa até agora , mas não funciona quando a mesma função é aninhada dentro de si mesma. Também é ineficiente e deselegante, com muitos problemas potenciais, então recorri ao Stack Overflow para obter ajuda para escrever uma melhor. Sinta-se à vontade para usá-la como ponto de partida!

Edição 2: aqui está o código da minha tentativa até agora:

constructs = {
    1: {
        1: {
            1: print,
        }
    }
}

def parse(code: list) -> list:
    if len(code) <= 1:
        return code
    result = []
    in_function = 0
    for i, token in enumerate(code):
        if in_function > 0:
            in_function -= 1
            continue
        if token == 0:
            continue
        if result and result[-1][0][3] != -1:
            if token in constructs and code[i + 1] in constructs[token] and code[i + 2] in constructs[token][code[i + 1]]:
                if i < len(code) - 4 and code[i + 4] == 0:
                    result[-1][-1].append(token)
                else:
                    if code[i + 3] == result[-1][0][3] + 1:
                        result[-1].append([])
                    result[-1][0] = code[i:i + 4]
                    in_function = 3
            else:
                result[-1][-1].append(token)
        else:
            if token in constructs and code[i + 1] in constructs[token] and code[i + 2] in constructs[token][code[i + 1]]:
                if code[i + 3] == 1:
                    result.append([code[i:i + 4], []])
                    in_function = 3
                else:
                    raise SyntaxError(f'function {code[i:i + 3]} has no previous separator {code[i + 3] - 1}')
            else:
                raise SyntaxError(f'function {code[i:i + 3]} was not recognized')
    for i, function in enumerate(result):
        result[i][0] = constructs[result[i][0][0]][result[i][0][1]][result[i][0][2]]
        for j, argument in enumerate(result[i][1:]):
            result[i][j + 1] = parse(argument)
    return result

Funciona para, parse([1, 1, 1, 1, 'Hello world', 1, 1, 1, 2, 'etc', 1, 1, 1, -1])mas não para parse([1, 1, 1, 1, 1, 1, 1, 1, 'Hello world', 1, 1, 1, -1, 1, 1, 1, 2, 'etc', 1, 1, 1, -1]).

python
  • 2 respostas
  • 125 Views
Martin Hope
Raildex
Asked: 2025-03-05 23:58:45 +0800 CST

adicionar argumentos (construtor) autocompletar

  • 10

Estou usando clangd no meu projeto C++.

Quando clangd sugere uma função, ele também insere marcadores de posição para as funções:
insira a descrição da imagem aqui

No entanto, quando eu digito um construtor, eu só recebo a janela de sobrecarga que eu posso percorrer. RETURN criará apenas parênteses vazios:
insira a descrição da imagem aqui

Posso fazer com que o clangd insira espaços reservados para parâmetros do construtor?

Editar:

Meus argumentos clangd:

"clangd.arguments": [
    "--pretty",
    "--compile-commands-dir=${workspaceFolder}/build",
    "--background-index",
    "--completion-style=detailed",
    "--header-insertion=iwyu",
    "--function-arg-placeholders"
],
$ clangd --version
clangd version 19.1.7

Edição 2:

Os placeholders já estão lá, só preciso rolar para baixo para um construtor em particular. É um pouco inconveniente.

insira a descrição da imagem aqui

c++
  • 1 respostas
  • 79 Views
Martin Hope
Hard_Course
Asked: 2025-03-03 10:08:22 +0800 CST

Correspondência de colunas em pares da esquerda para a direita em linhas de um dataframe para outro dataframe e adição de novas colunas com valores correspondentes

  • 10

Eu tenho um conjunto de dados como este:

 df1 <- data.frame(
    col1 = c(1, 2, 3),
    col2 = c(4, 5, 6),
    col3 = c(2, 8, 9),
    col4 = c(5, 11, 12),
    col5 = c(13, 14, 15),
    col6 = c(16, 17, 18),
    col7 = c(19, 20, 21),
    col8 = c(22, 23, 24)
  )

e um segundo que tem uma 'chave' de correspondências que estou procurando no df1:

df2 <- data.frame(
    colA = c(1, 2, 3),
    colB = c(4, 5, 6),
    value = c(100, 200, 300)
  )

o que estou tentando fazer é encontrar cada correspondência de coluna em pares da esquerda para a direita e criar uma nova coluna contendo o valor de df2 toda vez que houver uma correspondência, para que fique assim:

 df3 <- data.frame(
    col1 = c(1, 2, 3),
    col2 = c(4, 5, 6),
    col3 = c(2, 8, 9),
    col4 = c(5, 11, 12),
    col5 = c(13, 14, 15),
    col6 = c(16, 17, 18),
    col7 = c(19, 20, 21),
    col8 = c(22, 23, 24),
    match1 = c(100, 200, 300),
    match2 = c(200, NA, NA)
  )

Eu tentei esse tipo de abordagem:

df_match <- inner_join(df1, df2, by = c("col1" = "colA", "col2" = "colB"))
  
  df1$matched_value <- df_match$value[match(paste(df1$col1, df1$col2), paste(df_match$col1, df_match$col2))]

mas ele retorna apenas uma correspondência entre as linhas. O outro problema é que estou executando isso por muitas iterações que têm números variados de colunas em df1. Estou pensando que preciso de algo do tipo entre as linhas começa com 'col', mas estou bem travado.

  • 5 respostas
  • 94 Views
Martin Hope
Jabberwocky
Asked: 2025-02-27 18:58:12 +0800 CST

Como obter o número da versão do Windows SDK com o qual um programa está sendo compilado em tempo de compilação

  • 10

Gostaria de obter o número da versão do Windows SDK com a qual um programa está sendo compilado em tempo de compilação, como 10.0.22621.0 .

O mais próximo que consegui chegar foi algo assim:

#include <iostream>
#include <sstream>
#include <windows.h>

std::string NTDDIToFriendlyVersion(DWORD ntddiVersion) {
  DWORD major = (ntddiVersion & 0xFF000000) >> 24;
  DWORD minor = (ntddiVersion & 0x00FF0000) >> 16;
  DWORD build = (ntddiVersion & 0x0000FFFF);

  std::ostringstream oss;
  oss << major << "." << minor << "." << build;
  return oss.str();
}

int main() {
  std::cout << "WDK_NTDDI_VERSION is: " << std::hex << WDK_NTDDI_VERSION <<
            " (" << NTDDIToFriendlyVersion(WDK_NTDDI_VERSION) << ")\n";
}

que basicamente apenas disseca a WDK_NTDDI_VERSIONconstante definida em C:\Program Files (x86)\Windows Kits\10\Include\10.0.22621.0\shared\sdkddkver.h.

Resultado que obtenho:

NTDDI_VERSION is: a00000c (10.0.12)

Eu prefiro obter o 10.0.22621.0em vez de10.0.12


Marquei C e C++ porque realmente não me importo.

c++
  • 1 respostas
  • 114 Views
Prev
Próximo

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Reformatar números, inserindo separadores em posições fixas

    • 6 respostas
  • Marko Smith

    Por que os conceitos do C++20 causam erros de restrição cíclica, enquanto o SFINAE antigo não?

    • 2 respostas
  • Marko Smith

    Problema com extensão desinstalada automaticamente do VScode (tema Material)

    • 2 respostas
  • Marko Smith

    Vue 3: Erro na criação "Identificador esperado, mas encontrado 'import'" [duplicado]

    • 1 respostas
  • Marko Smith

    Qual é o propósito de `enum class` com um tipo subjacente especificado, mas sem enumeradores?

    • 1 respostas
  • Marko Smith

    Como faço para corrigir um erro MODULE_NOT_FOUND para um módulo que não importei manualmente?

    • 6 respostas
  • Marko Smith

    `(expression, lvalue) = rvalue` é uma atribuição válida em C ou C++? Por que alguns compiladores aceitam/rejeitam isso?

    • 3 respostas
  • Marko Smith

    Um programa vazio que não faz nada em C++ precisa de um heap de 204 KB, mas não em C

    • 1 respostas
  • Marko Smith

    PowerBI atualmente quebrado com BigQuery: problema de driver Simba com atualização do Windows

    • 2 respostas
  • Marko Smith

    AdMob: MobileAds.initialize() - "java.lang.Integer não pode ser convertido em java.lang.String" para alguns dispositivos

    • 1 respostas
  • Martin Hope
    Fantastic Mr Fox Somente o tipo copiável não é aceito na implementação std::vector do MSVC 2025-04-23 06:40:49 +0800 CST
  • Martin Hope
    Howard Hinnant Encontre o próximo dia da semana usando o cronógrafo 2025-04-21 08:30:25 +0800 CST
  • Martin Hope
    Fedor O inicializador de membro do construtor pode incluir a inicialização de outro membro? 2025-04-15 01:01:44 +0800 CST
  • Martin Hope
    Petr Filipský Por que os conceitos do C++20 causam erros de restrição cíclica, enquanto o SFINAE antigo não? 2025-03-23 21:39:40 +0800 CST
  • Martin Hope
    Catskul O C++20 mudou para permitir a conversão de `type(&)[N]` de matriz de limites conhecidos para `type(&)[]` de matriz de limites desconhecidos? 2025-03-04 06:57:53 +0800 CST
  • Martin Hope
    Stefan Pochmann Como/por que {2,3,10} e {x,3,10} com x=2 são ordenados de forma diferente? 2025-01-13 23:24:07 +0800 CST
  • Martin Hope
    Chad Feller O ponto e vírgula agora é opcional em condicionais bash com [[ .. ]] na versão 5.2? 2024-10-21 05:50:33 +0800 CST
  • Martin Hope
    Wrench Por que um traço duplo (--) faz com que esta cláusula MariaDB seja avaliada como verdadeira? 2024-05-05 13:37:20 +0800 CST
  • Martin Hope
    Waket Zheng Por que `dict(id=1, **{'id': 2})` às vezes gera `KeyError: 'id'` em vez de um TypeError? 2024-05-04 14:19:19 +0800 CST
  • Martin Hope
    user924 AdMob: MobileAds.initialize() - "java.lang.Integer não pode ser convertido em java.lang.String" para alguns dispositivos 2024-03-20 03:12:31 +0800 CST

Hot tag

python javascript c++ c# java typescript sql reactjs html

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve