Spec-Zone.ru › Octave 7

19.1 Базовая векторизация

С очень большой точностью, цель векторизации заключается в написании кода, избегающего циклов и использующего операции над целыми массивами. В качестве тривиального примера рассмотрим

for i = 1:n
  for j = 1:m
    c(i,j) = a(i,j) + b(i,j);
  endfor
endfor

по сравнению со значительно более простым

c = a + b;

Это не только проще для написания, но и внутренне гораздо проще для оптимизации. Octave делегирует эту операцию базовой реализации, которая, помимо других оптимизаций, может использовать специальные аппаратные инструкции для работы с векторами или, теоретически, может даже выполнять сложения параллельно. В общем случае, если код векторизован, базовая реализация имеет больше свободы в принятии предположений для достижения более быстрого выполнения.

Это особенно важно для циклов с "дешевыми" телами. Часто достаточно векторизовать только внутренний цикл, чтобы получить приемлемую производительность. Общее правило состоит в том, что "порядок" векторизованного тела должен быть больше или равен "порядку" окружающего цикла.

В качестве менее тривиального примера, вместо

for i = 1:n-1
  a(i) = b(i+1) - b(i);
endfor

напишите

a = b(2:n) - b(1:n-1);

Это демонстрирует важную общую концепцию использования массивов для индексирования вместо циклирования по переменной индекса. См. Выражения индексов. Также следует широко использовать булеву индексацию. Если необходимо проверить условие, это условие также может быть записано как булев индекс. Например, вместо

for i = 1:n
  if (a(i) > 5)
    a(i) -= 20
  endif
endfor

напишите

a(a>5) -= 20;

что использует тот факт, что a > 5 генерирует булев индекс.

Используйте поэлементные векторные операторы, когда это возможно, чтобы избежать циклов (операторы, такие как .* и .^). См. Арифметические операторы.

Также используйте векторизацию в этих поэлементных операторах, чтобы избежать циклов и ненужных промежуточных выделений памяти. См. Векторизацию.

Используйте встроенные и библиотечные функции, если это возможно. Встроенные и скомпилированные функции очень быстрые. Даже с m-файловой библиотечной функцией есть большая вероятность, что она уже оптимизирована или будет оптимизирована в будущих релизах.

Например, даже лучше, чем

a = b(2:n) - b(1:n-1);

это

a = diff (b);

Большинство функций Octave написаны с учетом векторных и массивно-ориентированных аргументов. Если вы обнаруживаете, что пишете цикл с очень простой операцией, скорее всего, такая функция уже существует. Следующие функции часто встречаются в векторизованном коде:

  • Манипуляции с индексами
    • find
    • sub2ind
    • ind2sub
    • sort
    • unique
    • lookup
    • ifelse / merge
  • Повторение
    • repmat
    • repelems
  • Векторизованная арифметика
    • sum
    • prod
    • cumsum
    • cumprod
    • sumsq
    • diff
    • dot
    • cummax
    • cummin
  • Форма многомерных массивов
    • reshape
    • resize
    • permute
    • squeeze
    • deal

© 1996–2022 The Octave Project Developers
Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies.
Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided that the entire resulting derived work is distributed under the terms of a permission notice identical to this one.
Permission is granted to copy and distribute translations of this manual into another language, under the above conditions for modified versions.
https://docs.octave.org/v7.2.0/Basic-Vectorization.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API