Spec-Zone.ru › Octave 6

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/v6.4.0/Basic-Vectorization.html

Spec-Zone.ru

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