In Place Element Structure дает ли реальные преимущества?

Общие принципы, проектирование, модуляризация, темплейты и шаблоны
Ответить
Аватара пользователя
Chupakabra

Tutorials
professional
professional
Сообщения: 360
Зарегистрирован: 21 янв 2009, 10:50
Награды: 1
Версия LabVIEW: 2015
Откуда: Москва
Поблагодарили: 4 раза
Контактная информация:

In Place Element Structure дает ли реальные преимущества?

Сообщение Chupakabra »

Решил погонять на время In Place Element Structure в следующем контексте.
Получилось, что время выполнения цикла с этой стурктурой даже немного больше чем без нее. Плюс еще видно, что выделяется какой-то буфер в структуре, от как.
Вложения
buff.PNG
Аватара пользователя
mzu2006

Professionalism Tutorials Black
doctor
doctor
Сообщения: 2456
Зарегистрирован: 16 авг 2008, 02:12
Награды: 3
Версия LabVIEW: 7.1 10 11 12
Откуда: St-Petersburg (RU), Phila, Boston, Washington DC
Контактная информация:

Re: In Place Element Structure дает ли реальные преимуществ

Сообщение mzu2006 »

Здесь дело не в структуре а в обвязке этой структуры.
1. Операция индексации "в ручную", достаточно "дорогая" по времени.
2. Выделение буфера мне тоже непонятно
3. Автоиндексация на границе счётного цикла очень эффективное средство.

Я использую "In place element structure" только для работы с DVR.
Аватара пользователя
Chupakabra

Tutorials
professional
professional
Сообщения: 360
Зарегистрирован: 21 янв 2009, 10:50
Награды: 1
Версия LabVIEW: 2015
Откуда: Москва
Поблагодарили: 4 раза
Контактная информация:

Re: In Place Element Structure дает ли реальные преимуществ

Сообщение Chupakabra »

mzu2006 писал(а):Здесь дело не в структуре а в обвязке этой структуры.
1. Операция индексации "в ручную", достаточно "дорогая" по времени.
2. Выделение буфера мне тоже непонятно
3. Автоиндексация на границе счётного цикла очень эффективное средство.

Я использую "In place element structure" только для работы с DVR.
Спасибо за ответы. Тогда еще вот такой вопрос.
Для случая изображенного на рисунке ниже, какой вариант более оптимален?
Первый наверное по памяти, второй по производительности?
И еще дает ли что использование вложенной (т.е. внутри первой) In place element structure, как показано в варианте 1?
Вложения
inplace1.png
Borjomy_1

Activity Professionalism Silver
doctor
doctor
Сообщения: 2210
Зарегистрирован: 28 июн 2012, 09:32
Награды: 3
Версия LabVIEW: 2009..2020
Откуда: город семи холмов
Благодарил (а): 27 раз
Поблагодарили: 26 раз

Re: In Place Element Structure дает ли реальные преимуществ

Сообщение Borjomy_1 »

Тема интересная, кстати. С чем регулярно сталкиваюсь: Есть большой массив (размером под 100000 элементов) кластера, в котором, в свою очередь, несколько массивов, строки. Если делать в лоб (как вариант 2), то скорость работы существенно падает. Спасает вариант 1. Если внимательно присмотреться, то видно, что расходы на память в первом случае радикально меньше.
Эта структура дает выигрыш, когда объемы данных значительны. Иначе заморачиваться особо смысла нет.
Аватара пользователя
IvanLis

Activity Professionalism Tutorials Gold Man of the year 2012
Автор
guru
guru
Сообщения: 5462
Зарегистрирован: 02 дек 2009, 17:44
Награды: 7
Версия LabVIEW: 2015, 2016
Откуда: СССР
Благодарил (а): 28 раз
Поблагодарили: 86 раз

Re: In Place Element Structure дает ли реальные преимуществ

Сообщение IvanLis »

Borjomy_1 писал(а):Тема интересная, кстати.
проводили мы тут практический эксперимент: In Place Element Structure
весьма интересные результаты
Borjomy_1

Activity Professionalism Silver
doctor
doctor
Сообщения: 2210
Зарегистрирован: 28 июн 2012, 09:32
Награды: 3
Версия LabVIEW: 2009..2020
Откуда: город семи холмов
Благодарил (а): 27 раз
Поблагодарили: 26 раз

Re: In Place Element Structure дает ли реальные преимуществ

Сообщение Borjomy_1 »

Насколько я понимаю способы распределения памяти в :labview: , неправильно экстраполировать тестирование на массиве элементов фиксированного размера на общие выводы о эффективности In Place.
Аватара пользователя
IvanLis

Activity Professionalism Tutorials Gold Man of the year 2012
Автор
guru
guru
Сообщения: 5462
Зарегистрирован: 02 дек 2009, 17:44
Награды: 7
Версия LabVIEW: 2015, 2016
Откуда: СССР
Благодарил (а): 28 раз
Поблагодарили: 86 раз

Re: In Place Element Structure дает ли реальные преимуществ

Сообщение IvanLis »

Borjomy_1 писал(а):Насколько я понимаю способы распределения памяти в :labview: , неправильно экстраполировать тестирование на массиве элементов фиксированного размера на общие выводы о эффективности In Place.
:dntknw:
Вы можете предложить свой вариант и показать полученные результаты
Что получилось, то и показал.
Аватара пользователя
mzu2006

Professionalism Tutorials Black
doctor
doctor
Сообщения: 2456
Зарегистрирован: 16 авг 2008, 02:12
Награды: 3
Версия LabVIEW: 7.1 10 11 12
Откуда: St-Petersburg (RU), Phila, Boston, Washington DC
Контактная информация:

Re: In Place Element Structure дает ли реальные преимуществ

Сообщение mzu2006 »

Я тоже не понял. Покажите Ваш код.
AndreyDmitriev

Activity Professionalism Tutorials Gold Black
VIP
VIP
Сообщения: 1327
Зарегистрирован: 03 фев 2010, 00:42
Награды: 6
Версия LabVIEW: 6.1 - 2024
Откуда: Германия
Благодарил (а): 1 раз
Поблагодарили: 38 раз
Контактная информация:

Re: In Place Element Structure дает ли реальные преимуществ

Сообщение AndreyDmitriev »

Конкретно InPlace структуру следует рассматривать как средство для сокращения расхода памяти при необоснованном выделении дополнительных буферов. Рассматривать её в качестве "турбо кнопки" было бы ошибочно, хотя в некоторых случаях она даёт прирост в производительности.

Давайте разбираться. Вообще говоря элементы для работы с массивами, строками, кластерами и иже с ними можно разделить на две группы - немодифицирующие, то есть операции чтения - Index Array, Cluster Unbundle, и т.д. и модифицирующие, то бишь операции записи - Replace Array, Delete, Cluster Bundle и т.д. При комбинировании этих элементов LabVIEW пытается по возможности уменьшить количество копий данных в памяти и использовать уже имеющиеся и выделенные буферы. Другое дело, что LabVIEW это не всегда удаётся, и иногда ей надо помочь - InPlace структура - это как раз тот костыль, который надо подставить, когда компилятор в затруднении.

Для начала вот такой пример:
Изображение

Как мы видим, у нас массив после цикла разделяется на две ветви, однако копии не создаётся. При этом нулевой элемент заменяется единицей, однако Index Array возвращает нуль, что ожидаемо. Почему не единицу, ведь буфер вроде как тот же? Состояния гонки здесь не возникает, потому что LabVIEW сначала выполняет операцию чтения, и лишь потом - операцию записи, хотя на блок диаграмме последовательность исполнения никак не задана. Стоит жёстко задать порядок выполнения - и будет выделен буфер, что удвоит количество используемой памяти:

Изображение
Если новый буфер не выделялся бы, то мы бы с удивлением обнаружили бы в нулевом элементе единицу при чтении во втором окне фрейма.

Другой пример - две операции чтения и две записи:

Изображение

Тут я кружком отметил место, где выделяется новый буфер. Это происходит оттого, что у нас есть две операции записи, и результат второй операции (output array 2) не должен менять массив "output array". Ну и так далее.

Едем дальше. Часто операции чтения и записи комбинируются вот таким образом:

Изображение

Здесь дополнительных буферов не выделяется и замена этой конструкции на InPlace структуру в смысле экономии памяти нам ничего не даст, кроме уменьшения количества проводников. С точки зрения операций - в Inplace будут использованы те же самые Index/Replace, так что в производительности мы особого выигрыша не получим, что и наблюдается на некоторых тестах. Боле того, на старых версиях InPlace структура может даже привести к небольшому замедлению по сравнению с Index/Replace, однако в LabVIEW 2011 по производительности они сравняются. Впрочем я наблюдал ситуации, когда InPlace структура давала определённый выигрыш в производительности - это, по видимому зависит от того, как компилятор отработает.

Теперь попробуем найти ситуацию, когда InPlace "работает". Давайте чуть изменим наш код:

Изображение

Вроде ничего принципиально не изменилось, однако, наткнувшись на константу, LabVIEW выделила нам буфер для операции записи, совершенно не нужный. Возьмите также на земетку, что буфер у Replace Array появился от изменения кода источника данных - это значит, что изменив код на одном конце даграммы, можно получить изменения в совершенно неожиданном месте. Тем не менее результат - количество расходуемой памяти возросло вдвое, кроме того, код стал медленнее (на массиве размером этак в сотню мегабайт десять-двадцать миллисекунд мы, вероятно потеряем).
Вот для этой ситуации нам и нужна InPlace структура:

Изображение

Здесь дополнительного расхода памяти нет, код этот выполняется значительно быстрее. Сравните выделение буферов на этом коде со скриншотом выше и вы увидите разницу.

Вообще National Instruments пишет об этой структуре довольно расплавчато - она уменьшит количество расходуемой памяти "в некоторых случаях". Будет она "работать" или нет и даст ли преимущество — зависит от внешних элементов, наличия других модифицирующих элементов и порядка их выполнения и т.д. В некоторых случаях можно запросто получить дополнительный буфер на входе в InPlace структуру. Единственное, что гарантируется - внутри самой структуры копии массива создано не будет.

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

Отдельно имеет смысл поговорить вот об этом буфере - в самом первом посте был вопрос:

Изображение

Это происходит оттого, что LabVIEW работает с элементами массива "по значению", каждый раз перебрасывая элемент во временный буфер. Это хорошо видно и на ассемблерном листинге. Ну а в терминах язака Си там происходит всегда что-то вроде

int temp;
int arr[1000];

temp = arr[0];
temp = temp + 1;
arr[0] = temp;

В то время как нормальный компилятор просто сделал бы

int arr[1000];

arr[0]++;

Последния версия LabVIEW выдаёт довольно производительный код, но до скорости интеловского или майкрософтовского компиляторов ещё ой как далеко, так что если нужна действительно высокая скорость исполнения, то по-прежнему придётся генерять свою DLL.

Вообще когда мы упираемся в чересчур большой расход памяти или недостаточную производительность, то надо каждый конкретный случай рассматривать индивидуально. Универсальных рецептов тут нет. В общем случае не стоит использовать Build Array - это очень "дорогая" операция. Массивы в циклы загонять через сдвиговые регистры. При автоиндексации на границах цикла контролировать, что не создаётся буфер на выходе - вот, к примеру в третьем посте сверху мы видим, что буфера создаются на выходе двух вложенных циклов - это аргумент в пользу замены автоиндексации на сдвиговые регистры, либо упрощения типа данных. Использовать опять же InPlace структуру. Вообще ситуация, когда производительности не хватает "чуть-чуть" - она довольно редкая (в моей практике во всяком случае). Либо идёт работа с небольшими внутренними массивами, где производительность не важна, либо с очень большими объёмами, где производительность никакими InPlace структурами не вытянешь - тогда приходится подключать внешний код. Да и вообще - оптимизация без причины — признак ..., ну вы поняли :D .

По сути вопроса, прозвучавшего в третьем посте:

В данном случае вот такая структура неоптимальна, потому что идёт выделение буферов:

Изображение

Более оптимально (причём не только с точки зрения расхода памяти, но и с точки срения производительности) сделать как-то вот так:

Изображение

InPlace структура в смысле экономии памяти нам тут ничего не даст, но посмотрите, насколько красивее стал код, да и работает он едва ли не вдвое быстрее (к сожалению разумного объяснения тут нет, единственное, что приходит в голову - дизассемблировать код да сравнить, однако делать это лень):

Изображение

Ну и на закуску - многие (и я в том числе) ленятся подключать терминал N, а используют автоиндексацию для задания количества итераций цикла for, а напрасно:

Изображение
Двойной расход памяти, так как в сдвиговый регистр отправилась копия массива, плюс очевидные пенальти по производительности.

Дисклаймер - на вопросы "почему вот здесь буфер выделяется а вот тут - нет и там быстрее - а сям медленнее" отвечать довольно сложно, так как это лежит в большой степени на совести компилятора и небольшая модификация программы может привести к кардинальным изменениям. Где кроется истина - знает лишь NI, так что всё вышенаписанное не воспринимайте как аксиому - это просто пища для размышлений.

Ну и список литературы, ессно, там по большей части всё изложено:

In Place Element Structure
Array Index / Replace Elements Border Node
In Place Element Structures: Increasing Memory Efficiency
VI Memory Usage
Memory Management for Large Data Sets (раздел "Reducing Copies of Large Data Sets")
Igor_G
assistant
assistant
Сообщения: 126
Зарегистрирован: 06 ноя 2011, 14:10
Версия LabVIEW: 2012-2016
Контактная информация:

Re: In Place Element Structure дает ли реальные преимуществ

Сообщение Igor_G »

Работает и дает положительный результат достаточно наглядно,
но испольсовать ее мне пока правильно достаточно сложно. Почему?
Это достаточно хорошо описал уже AndreyDmitriev.
Вложения
In Plase Element Structure.png
Ответить
  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «Модели программирования»