2017-02-22 6 views
0

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

например. если есть 10 элементов мне нужно выполнить следующую операцию до получения окончательного ответа

var_and= A1 && A2; 
var_and=var_and && A3;.. 
. 
. 
var_and=var_and && A10; 

Это как сборка код будет выглядеть (?).

Есть ли лучшее решение для этого?

+1

Кто отвечает за ввод значения? Может быть, там есть флаг и вообще пропустить контрольную часть? –

+0

@SouravGhosh Первоначально все значения будут равны нулю и одновременно или могут быть поодиночками, каждое значение станет некоторым ненулевым значением. – user413201

+1

Нулевой счетчик. Процедуры, которые добавляют/удаляют/мутируют числа в наборе, должны обновить счетчик нулей. –

ответ

4

Наиболее эффективный способ сделать это наиболее определенно

std::any_of(v.begin(),v.end(),[](int x) { return x==0; }); 

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

Но самое главное, что вы сохраняете свое время, которое может быть потрачено впустую на подсчет инструкций ассемблера (что почти не имеет смысла) и время потенциальных читателей вашего кода.

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

Также другой близкий вариант

std::find(v.begin(),v.end(),0)!=v.end(); 
+0

У меня нет такого современного компилятора, как у вас - можете ли вы рассказать о своем ответе по сравнению с тем, который указан в http://stackoverflow.com/a/42384605/558639, и опубликовать результаты? Я готов быть впечатлен ... –

+1

@fearless_fool хорошая вещь у нас есть компиляторы [здесь] (https://godbolt.org/g/dYbrZQ) :) Как вы можете видеть, MSVC (CL 19) произвел в значительной степени тот же код, другие (GCC, Clang, ICC), которым удалось выполнить некоторую циклическую разворачивание с помощью «std :: any_of», может быть несколько полезен, зависит от конкретного случая. Мои локальные измерения практически не отличались от таймингов, и я думаю: D – Ap31

+1

Сайт godbolt.org - БОЛЬШОЙ инструмент: в этом случае ваш подход any_of() испускает 5 инструкций во внутреннем цикле, старый школьный чистый C "код испускает 7. Подумайте, я впечатлен, и спасибо за просветление! –

2

Первое, что нужно отметить, это то, что «самый эффективный» находится в глазах смотрящего. Вы имеете в виду быстрее всего? Самое маленькое кодовое пространство? Проще всего поддерживать?

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

Так что, возможно, я что-то пропустил - следующее кажется слишком простым - но делает ли это то, что вы хотите?

bool has_a_zero(int *values, int n) { 
    while (n--) { 
    if (!*values++) return true; 
    } 
    return false; 
} 

Если это не достаточно быстро, вы можете делать трюки, как разворачивая цикл, чтобы сделать куски N испытаний в то время (например, Duff's Device). Или, если ваш набор значений имеет внеполосное значение, вы можете использовать его для завершения цикла, а не для обработки дополнительных регистров.

Но, как бы то ни было, вам нужно будет объяснить немного больше, что вы подразумеваете под «наиболее эффективным».

+0

Эффективным я имею в виду быстрый с меньшим количеством машинных инструкций. – user413201

+4

Меньше инструкций не обязательно означает ускорение? – stijn

+0

Всего несколько инструкций? Или меньше всего выполнено? А если последнее, в среднем случае или в худшем случае? Считайте, что остановка с первым найденным нулем не помогает в худшем случае, но, скорее всего, создает больше кода. Развертка цикла часто выполняется быстрее, но дает больше инструкций. – TrentP

Смежные вопросы