Сабж. Иногда нужно проверить крупную область памяти на предмет равенства нулю, единице.
Поэтому вопрос:
Оптимизирует ли компилятор циклы вида
bool b = true; for(int i = 0; i < 100500; i++) if( mas[i]) b = false;
И если нет, то как их можно написать оптимальнее.
bool b; int i; for(i = 0; i < 100500; i++) if( mas) break; b = ( i!=100500);
-Eugene-
я думаю этот цикл не выполнится ни разу
Влюблённый металлист
Забыл про тег code. Поправлю
А не проще предусмотреть для данноего массива счетчик истинных значений?
При модификации массива корректировать значение счетчика.
Затем просто проверять этот счетчик - если ноль то b=true иначе false.
-Eugene-
> И если нет, то как их можно написать оптимальнее.
Для поиска нуля - memchr, для поиска не нуля (при условии, что 1-й байт нуль, что можно проверить отдельно) - memcmp(massiv, massiv+1 байт, 100499).
По идее, оптимальнее некуда, ибо интринсик.
Ну и со счётчиком истинности, собственно, тут тоже хорошо подсказали - это ещё оптимальнее. :)
Похоже эта операция кандидат на Memory-Bandwidth bounded. Т.е. скорость её выполнения будет во многом упираться в скорость передачи память - кеш, особенно если блоки будут ещё больше.
Кстати, что за тип элементов масива? char или int, или что-то ещё? Если char, то можно извратиться через сравнивания int'ами N / sizeof(int) итераций + обычным циклом остаток N % sizeof(int).
Ищем сумму всего масива, и потом ОДНА проверка на ноль.
Tonal
> Ищем сумму всего масива, и потом ОДНА проверка на ноль.
И получаем самое большое время выполнения.
К тому же сложение лишь на одну инструкцию короче сравнения с условным переходом.
Идея с счетчиком хороша лишь если проверку нужно делать достаточно часто. Т.к. запись в массив становится не очень быстрой.
Если счетчик не подходит - можно ассемблером:
CX <= 100500
AX <= 0
ES:DI <= mas
REPE SCAS
Хотя возможно есть механизмы и по шустрее в новых инструкциях )
Tonal, идея с суммированием хороша до тех пор пока сумматор не обнулился )
-Eugene-
Для таких вещей хорошо бы использовать что-то похожее на операцию reduce (параллельная редукция).
Она может быть реализована по разному в зависимости от библиотеки, но на CPU скажем в intel tbb оптимизирована под многоядерность, а это буст.
Можно OpenMP попробовать, там тоже есть reduce. Далее, SSE использовать, но это не факт что что-то даст.
Тут скорость упрется в скорость памяти, не может быть чтобы это отнимало относительно большую часть времени.
Altmer
А если суммировать по модулю 2? :)
Tonal
Вероятность косяка в таком случае только возрастет. 1^1 = 0
Но например логическое ИЛИ подойдет.
А вообще непонятно зачем подобное вообще понадобилось )
Altmer
> Но например логическое ИЛИ подойдет.
да прогон вышел, я имел ввиду лог. ИЛИ
Тема в архиве.