2012-01-23 2 views
10

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

  1. сравнить каждый элемент к нулю, в результате чего 40, если заявления.
  2. выделение аналогичной структуры, которая уже обнулена и memcmp со структурой.
  3. обертывание структуры в союзе с типом, достаточно большим, чтобы покрыть все это.

, например

typedef union { 
    struct { 
    uint8_t a; 
    uint8_t b; 
    } 
    uint16_t c; 
} STRUCTURE_A; 

, а затем сравнивая его к нулю.

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

+0

Что случилось с простой проверкой всей структуры в выражении 'if', например, для флага нуля? –

+3

Не забывайте про прокладку! – NPE

+1

Вы реализовали каждый из трех разных способов и сравнили их производительность? Что ты нашел? –

ответ

15

Сравнить каждый элемент структуры 0.

Это единственный безопасный способ сравнения двух объектов структур (даже если один из объектов структуры имеет все члены устанавливается значение 0). Не используйте memcmp для сравнения структуры, значение байтов заполнения в структуре не указано. Обратите также внимание на то, что не разрешается использовать оператор == с операндами структурных объектов.

Смотрите эту ссылку с-FAQ по сравнению структуры объекта:

Q: Is there a way to compare structures automatically?

+1

Если вы гарантировали, что структура не содержит отступов, 'memcmp' является безопасным. В то время как для реализации технически разрешено добавлять произвольное бессмысленное заполнение, в реальном мире заполнение чисто для выравнивания, а правильно построенная, естественно выровненная структура не будет заполнять, кроме потенциально в конце. В частности, использование 'intX_t' и упорядочение их без разрывов выравнивания - хороший способ избежать заполнения. –

+0

Если структура не содержит отступов, а 'memcmp' на самом деле * быстрее *, оптимизатор обязательно увидит это и соответствующим образом преобразует ваши сравнения. –

+0

Надеюсь, что ... –

1

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

0

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

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

int iszero(void * ptr, int bytes) 
{ 
    char * bptr = (char*)ptr; 
    while(bytes--) 
    if(*bptr++) 
     return 0; 
    return 1; 
} 

Затем оптимизируйте, чтобы выполнить сопоставления по словам. Ознакомьтесь с реализацией Newlib таких вещей, как strlen() & memcpy() для примеров того, как это делается.

+0

Это эквивалентно 'memcmp' и может иметь проблемы с заполнением. –

+0

@R .. Нет, это не эквивалентно memcmp(), потому что здесь нет никакой нулевой структуры излишков. Дополнительный доступ к памяти в memcmp(), вероятно, хуже, чем удвоение времени доступа к памяти, потому что вы делаете два чтения каждый раз, и вы, вероятно, имеете разбиение кеша на больших структурах. Я не рассматривал проблемы с заполнением. Но если вы знаете, что нет дополнения (например, в GCC, использующем пакет pragma), я соглашусь на мой аргумент, что этот метод является самым быстрым. –

+0

Под «эквивалентом» я имел в виду, что он имеет такое же поведение (и проблему заполнения), но я предлагаю вам сравнить производительность. Ваш код (байтовый байт) настолько медленный, что даже при нескольких чтениях 'memcmp' должен побеждать. Хороший 'memcmp' сравнивает 4, 8 или даже 16 байтов за раз. BTW «упакован» не является способом устранения проблем с выравниванием. Мой комментарий к ответу ouah - правильный путь. –

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