Массив с нулём

Все, что вы хотели знать о программизме, но боялись спросить.
Ответить
tiasur
Маньяк
Сообщения: 1510
Зарегистрирован: 26 фев 2006, 10:00
Откуда: offline

Сообщение tiasur »

aissp писал(а):Давай на соображалку а то мармот скучает 8)
давай по очереди
так что втот конкретный вопрос может ожидает, что ты будешь
свертку по лапласу использовать или еше чего .. зависит от
контекста, который собсно приходиця выжимать из тиасура
как раба из чехова
контекста - embedded system
Аватара пользователя
sz
Маньяк
Сообщения: 1266
Зарегистрирован: 17 фев 2003, 19:34

Сообщение sz »

Marmot писал(а):
aissp писал(а):Давай на соображалку а то мармот скучает 8)
Да нет, сейчас опять в забой, работать надо :(
Я тут пока жую, каморю потихоньку...
Хех, а я как раз во время работы больше всего и пишу :)
Запустил на компиляцию - проверил, что написали.
Пофиксил errors, запустил на компиляцию, пошел ответил.

А когда я не пишу никуда - это значит, что либо я вообще на всю работу забил, либо дизайн обдумываю и в голове свободного процессорного времени не осталось - все ядра заняты, весь кеш забит.
tiasur
Маньяк
Сообщения: 1510
Зарегистрирован: 26 фев 2006, 10:00
Откуда: offline

Сообщение tiasur »

Мне кажется правильным решением будет найти наименьшее число массива и затем сравнить его с нулем. Сравнение двух чисел идёт быстрее, чем проверка на нуль? В задаче не сказано, что в массиве могут быть орицательные числа.
Аватара пользователя
nemiga
Маньяк
Сообщения: 2425
Зарегистрирован: 02 сен 2006, 19:05
Откуда: Minsk -> Seoul -> Ottawa

Re: Массив с нулём

Сообщение nemiga »

tiasur писал(а):Как проверить массив на наличие там нуля не перебирая его члены?
Если разрядность процессора невелика (напр, 8), то я бы делал так:

Пусть искомый массив А длиной LEN_А лежит с адреса A_BEG

Тогда:

MOV A_BEG, R1
MOV LEN_A+1, R2
again: DEC R2
JMP @ const+R2+R1

JZ R2, nonzero

const: JMP zero
const+1: JMP again
const+1: JMP again
const+1: JMP again
...
const+LEN_A:JMP again

nonzero: ... ; нет нулей
zero: ... ; есть нуль

.

Никаких умножений и делений. Только +, -, и переход. Lookup table: переход по косвенному адресу, который получается сложением i-го элемента массива с некой константой. По всем адресам перехода кроме однонго записан возврат. В строке, куда перейдем, если элемент массива ноль, записан переход на обработку данного случая.

Если пробежав по всему массиву так и не прыгнули на адрес, соответствующий нулю, то переходим на оьработку случая "нуля нет".

.
Аватара пользователя
ajkj3em
Маньяк
Сообщения: 2063
Зарегистрирован: 12 ноя 2006, 06:53

Re: Массив с нулём

Сообщение ajkj3em »

nemiga писал(а):Если разрядность процессора невелика (напр, 8), то я бы делал так:
A.k.a. computed goto :)
Аватара пользователя
AlexANB
Маньяк
Сообщения: 2904
Зарегистрирован: 17 фев 2003, 18:47
Откуда: Ontario

Re: Массив с нулём

Сообщение AlexANB »

tiasur писал(а):Как проверить массив на наличие там нуля не перебирая его члены?
Да бросьте вы фигней маяться! Вона уже сколько страниц впустую написали...

Ежику понятно, что мгновенно решается это только либо квантовым компьютером, либо аналоговой машиной, либо на хардверном уровне (восемь бит каждой ячейки памяти сводятся на схему ИЛИ, а весь массив байтов -- на схему И)
tiasur
Маньяк
Сообщения: 1510
Зарегистрирован: 26 фев 2006, 10:00
Откуда: offline

Сообщение tiasur »

Приходится по новому смотреть на некоторые вещи. Например, сейчас, кажется, что != выполняется быстрее чем ==.
Аватара пользователя
Azazello
Житель
Сообщения: 769
Зарегистрирован: 16 янв 2007, 04:31

Сообщение Azazello »

ajkj3em писал(а):чем-то напоминает вот это - http://www.mailcom.com/TemplatedSQRT.html
Sweet ;)...
tiasur писал(а):Определить есть ли ноль в массиве не сравнивая каждый член этого массива с нулем. Можно использовать другие математические операции. Сравнение с нулём может быть произведено только один раз. Код должен получиться в результате оптимизированным. Язык С.
...
Сомневаюсь что Ваше решение оптимизированное vs. с перебором и сравнением каждого члена с 0.
То есть, в принципе должно быть одно сравнение, то есть даже loop нельзя прерывать? Так как прерывание loop ЛОГИЧЕСКИ следует из логического условия, что элемент равен нулю, как бы мы это не обставили, то в итоге мы всё-таки сравниваем элемент с нулём. Получается, что мы вынуждены пробежать весь массив, получить некий результат, который зависит от наличия нуля в массиве, а затем проверить значение этого результата. А это, в общем случае, как мне кажется, очевидным образом неэффективно по сравнению с прерыванием loop в момент нахождения нуля... Или под сравнением имеют ввиду только if( Element == 0 ), и

Код: Выделить всё

int *lCrt = fArray, *lEnd = fArray + fSizeOfArray - 1;

while( *lCrt && lCrt++ <= lEnd );

cout << ( lCrt > lEnd ? " No suckers :(..." : "Gotcha, sucker ;)..." ) << endl;
катит (хотя, конечно, это одно и тоже)?
В этом смысле, мой шутливый пример с exception становится вполне разумным ;) - нигде нет проверки на ноль - ни в внутри loop, ни завуалированной проверки в условии loop. И, дико, но, по-моему, это оптимизированное решение по отношению к заведомому проходу по всему массиву произвольного размера с нулём в произвольном элементе... Впрочем, это была шутка в любом случае ;)...
То есть, с моей точки зрения, задача некорректно поставлена.
Аватара пользователя
sz
Маньяк
Сообщения: 1266
Зарегистрирован: 17 фев 2003, 19:34

Сообщение sz »

А это, в общем случае, как мне кажется, очевидным образом неэффективно по сравнению с прерыванием loop в момент нахождения нуля... Или под сравнением имеют ввиду только if( Element == 0 ), и
Неправильно. Пробежка по массиву - это последовательный доступ к данным. Происходит очень быстро - прямо в кеше процессора.
А проверка на прерывание - это, как минимум одна потеря бранча. Практически всегда медленнее. Ну, при разумных размерах массива, разумеется.

Ключевой вопрос нынешних оптимизаций состоит в том, что часто быстрее посчитать, чем проверить, стоит ли.
Аватара пользователя
Baguk
Маньяк
Сообщения: 2365
Зарегистрирован: 25 янв 2007, 12:55
Откуда: UA->AZ->IL->CA

Сообщение Baguk »

Обратите внимание, что в исходном цикле 2 сравнения: с нулём и на конец массива. Может, задача была в том, чтобы избавиться от одного из них? Тогда существует решение.
Аватара пользователя
Sheen
Маньяк
Сообщения: 2135
Зарегистрирован: 13 фев 2006, 21:16

Сообщение Sheen »

А массив вначале отсортировать нельзя? Т.е. процессор будет тратить больше времени на вставку значения, зато самое минимальное всегда будет первым.
Аватара пользователя
Azazello
Житель
Сообщения: 769
Зарегистрирован: 16 янв 2007, 04:31

Сообщение Azazello »

sz писал(а):Неправильно. Пробежка по массиву - это последовательный доступ к данным. Происходит очень быстро - прямо в кеше процессора.
А проверка на прерывание - это, как минимум одна потеря бранча. Практически всегда медленнее. Ну, при разумных размерах массива, разумеется.
Допустим, массив из N элементов только с ОДНИМ нулём в произвольном элементе (напоминаю, в оригинальной задаче нулей может быть несколько - хоть весь массив из нулей).
Способ #1: пробежать весь массив, скажем, перемножая элементы, и результат сравнить с нулём. Время на работу с одним элементом - t1. Время на выполнение ВСЕГДА - N*t1.
Способ #2: loop с выходом, если элемент равен нулю. Время на работу с одним элементом - t2. Какое, в среднем, время мы потратим на поиск нуля в произвольном элементе? На вскидку, N(1 + N)*t2/2N =~ N*t2/2.

Вывод: Если я не ошибся, пробег всего массива выгоден только если t1 < t2/2. Какая, из удовлетворяющих условию задачи, операция с элементом будет в два раза быстрее, чем сравнение с нулём? Умножение? Деление? Сравнение двух произвольных чисел? Я деталей того, как процессоры работают не знаю, но задача, как я понимаю, ЛОГИЧЕСКАЯ - произвольный процессор, произвольный компилятор. sz, Вы в процессорах "шарите" ;), серьёзно, неужели Способ #1 может быть быстрее на каком-то процессоре? А какая операция тогда используется?
Аватара пользователя
sz
Маньяк
Сообщения: 1266
Зарегистрирован: 17 фев 2003, 19:34

Сообщение sz »

tiasur писал(а):Мне кажется правильным решением будет найти наименьшее число массива и затем сравнить его с нулем. Сравнение двух чисел идёт быстрее, чем проверка на нуль? В задаче не сказано, что в массиве могут быть орицательные числа.
Сравнение двух чисел и проверка на 0 - одна фигня.
Но можно использовать функцию min(abs(*a)). Правильные их имплементации не содержат никаких ифов.
Но вообще-то, тот код, который я ранее написал полностью и правильно отвечает на вопрос. Я абсолютно уверен, что это именно то, что они ждут.
Аватара пользователя
Аман Ванкуверский
Маньяк
Сообщения: 2759
Зарегистрирован: 18 окт 2005, 01:10

Сообщение Аман Ванкуверский »

Sheen писал(а):А массив вначале отсортировать нельзя? Т.е. процессор будет тратить больше времени на вставку значения, зато самое минимальное всегда будет первым.
тогда следует включать дополнительные условия о том как часто производится добавление элементов и поиск нулевого. потому что сортировать массив из m или пусть даже n элементов 10 раз, чтобы один раз вытащить из него нулевое значение заведомо неэффективно
Аватара пользователя
Sheen
Маньяк
Сообщения: 2135
Зарегистрирован: 13 фев 2006, 21:16

Сообщение Sheen »

Ну да, согласен, фигня получается ... так может тогда завести одну маленькую (а можно и побольше) переменную и при добавлении значения в массив, если значение нулевой, помещать на него ссылку. Когда надо будет это нулевое значение вытащить ... [лень набирать дальше]
Ответить