Partilhar via


Algoritmos STL MSVC vetorizados

Sob condições específicas, os algoritmos na STL (Standard Template Library) do MSVC podem processar vários elementos simultaneamente em um único núcleo de CPU, em vez de lidar com cada elemento individualmente. Essa otimização usa instruções de instrução única, vários dados (SIMD) fornecidas pela CPU, uma técnica chamada vetorização. Quando essa otimização não é aplicada, a implementação é chamada de escalar.

As condições necessárias para a vetorização são:

  • O contentor ou a gama devem ser contíguos. Exemplos incluem array, vectore basic_string. Tipos como span e basic_string_view fornecem gamas contíguas. Matrizes integradas também formam intervalos contíguos. Os contentores gostam list e map não são contíguos.
  • A plataforma de destino deve suportar as instruções SIMD necessárias para implementar o algoritmo para os tipos de elementos. Isto é tipicamente verdadeiro para tipos aritméticos e operações simples.
  • Deve ser preenchida uma destas condições:
    • O compilador pode emitir código de máquina vetorizado para uma implementação escrita como código escalar (autovetorização).
    • A implementação do algoritmo usa explicitamente código vetorizado (vetorização manual).

Autovetorização no STL MSVC

Para obter mais informações sobre vetorização automática, consulte Auto-Vectorizer e a discussão nesse artigo sobre o /arch switch. Isso se aplica ao código de implementação STL da mesma forma que se aplica ao código do usuário.

Algoritmos como transform, reducee accumulate se beneficiam fortemente da vetorização automática.

Vetorização manual no MSVC STL

Certos algoritmos para x64 e x86 incluem vetorização manual. Essa implementação é compilada separadamente e depende do despacho da CPU em tempo de execução, portanto, ela se aplica apenas a CPUs adequadas.

Algoritmos vetorizados manualmente usam metaprogramação de modelo para detetar se o tipo de elemento é adequado para vetorização. Como resultado, eles são vetorizados apenas para tipos simples, como tipos inteiros padrão.

Os programas se beneficiam em desempenho da vetorização manual ou não são afetados por ela. Desative a vetorização manual definindo _USE_STD_VECTOR_ALGORITHMS=0 em seu projeto. Os algoritmos vetorizados manualmente são habilitados por padrão em x64 e x86 porque _USE_STD_VECTOR_ALGORITHMS o padrão é 1 nessas plataformas.

Atribua o mesmo valor a _USE_STD_VECTOR_ALGORITHMS todas as unidades de tradução vinculadas que usam algoritmos. Configure-o nas propriedades do projeto em vez de no código-fonte para consistência. Para obter mais informações sobre como configurá-lo, consulte /D (Definições de pré-processador).

A _USE_STD_VECTOR_ALGORITHMS macro controla o comportamento desses algoritmos vetorizados manualmente:

  • contains, contains_subrange
  • find, find_last, find_end, find_first_of, adjacent_find
  • count
  • mismatch
  • search, search_n
  • swap_ranges
  • replace
  • remove, remove_copy
  • unique, unique_copy
  • reverse, reverse_copy
  • rotate
  • is_sorted, is_sorted_until
  • lexicographical_compare, lexicographical_compare_three_way
  • max, min, minmax
  • max_element, min_element, minmax_element

A _USE_STD_VECTOR_ALGORITHMS macro também controla a vetorização manual de:

  • basic_string e basic_string_view membros:
    • find
    • rfind
    • find_first_of, find_first_not_of
    • find_last_of, find_last_not_of
  • bitset construtores de string e bitset::to_string

Algoritmos vetorizados manualmente para tipos de ponto flutuante

A vetorização de tipos de vírgula flutuante envolve considerações específicas:

  • A vetorização pode reordenar as operações, o que pode afetar a precisão dos resultados de vírgula flutuante.
  • Os tipos de vírgula flutuante podem conter NaN valores, que não se comportam transitivamente em comparações.
  • Operações de ponto flutuante podem gerar exceções.

O STL aborda as duas primeiras considerações com segurança. Apenas max_element, min_element, minmax_element, , max, min, minmax, is_sortede is_sorted_until são vetorizados manualmente. Estes algoritmos:

  • Não calcule novos valores de vírgula flutuante. Em vez disso, eles comparam os valores existentes para garantir que as diferenças na ordem de operação não afetem a precisão.
  • Como esses são algoritmos de classificação, NaN os valores não são permitidos como entradas.

Use _USE_STD_VECTOR_FLOATING_ALGORITHMS para controlar o uso desses algoritmos vetorizados para tipos de vírgula flutuante. Defina-o como 0 para desativar a vetorização. _USE_STD_VECTOR_FLOATING_ALGORITHMS não afeta nada se _USE_STD_VECTOR_ALGORITHMS estiver definido como 0.

O _USE_STD_VECTOR_FLOATING_ALGORITHMS padrão da macro é 0 quando /fp:except é definido.

Atribua o mesmo valor a _USE_STD_VECTOR_FLOATING_ALGORITHMS todas as unidades de tradução vinculadas que usam algoritmos. Configure-o nas propriedades do projeto em vez de no código-fonte para consistência. Para obter mais informações sobre como configurá-lo, consulte /D (Definições de pré-processador).

Consulte também

Auto-vetorizador