Немного поля больше эффективно (в вычислительном отношении), чем маскирование битов и извлечение данных вручную?

Попытайтесь поместить'!' метка перед шаблоном, которому Вы не хотите соответствовать - помещение

!*.cgi, !*.pm, !*.sql

в разделе шаблонов Имени файла, делает задание в тесте, который я делаю с Eclipse 3.4.1 (когда шаблон был просто * был файл каждого типа с тем шаблоном, это только возвращает js и мн файлы).

я боялся, что это будет немного наивно с шаблонами и просто позволит что-либо, что соответствовало одному из них для следования (т.е. sql файл будет соответствовать! *.cgi), но это, кажется, не имеет место.

8
задан Jonathan Leffler 27 September 2009 в 17:40
поделиться

7 ответов

Компилятор генерирует те же инструкции, которые вы бы явно написали для доступа к битам. Так что не ожидайте, что это будет быстрее с битовыми полями.

Фактически, строго говоря, с битовыми полями вы не контролируете, как они позиционируются в слове данных (если ваш компилятор не дает вам дополнительных гарантий. Я имею в виду, что Стандарт C99 ничего не определяет). Делая маски вручную, вы можете по крайней мере разместить два наиболее часто используемых поля первым и последним в серии, потому что в этих двух положениях требуется одна операция вместо двух, чтобы изолировать поле.

9
ответ дан 5 December 2019 в 06:54
поделиться

Those will probably compile the the same machine code, but if it really matters, benchmark it. Or, better yet, just use the bitfield because it's easier!

Quickly testing gcc yields:

shrq    $6, %rdi             ; using bit field
movl    %edi, %eax
andl    $31, %eax

vs.

andl    $130023424, %edi     ; by-hand
shrl    $21, %edi
movl    %edi, %eax

This is a little-endian machine, so the numbers are different, but the three instructions are nearly same.

6
ответ дан 5 December 2019 в 06:54
поделиться

In this examle I would use the bit field manually.
But not because of accesses. But because of the ability to compare two dt's.
In the end the compiler will always generate better code than you (as the compiler will get better over time and never make mistakes) but this code is simple enough that you will probably write optimum code (but this is the kind of micro optimization you should not be worrying about).

If your dt is an integer formatted as:

yyyyyyyyyyyy|mmmm|ddddd|hhhhh|mmmmmm

Then you can naturally compare them like this.

dt t1(getTimeStamp());
dt t2(getTimeStamp());

if (t1 < t2)
{    std::cout << "T1 happened before T2\n";
}

By using a bit field structure the code looks like this:

dt t1(getTimeStamp());
dt t2(getTimeStamp());

if (convertToInt(t1) < convertToInt(t2))
{    std::cout << "T1 happened before T2\n";
}
// or
if ((t1.year < t2.year)
    || ((t1.year == t2.year) && ((t1.month < t2.month)
      || ((t1.month == t2.month) && ((t1.day < t2.day)
        || ((t1.day == t2.day) && (t1.hour  etc.....

Of course you could get the best of both worlds by using a union that has the structure on one side and the int as the alternative. Obviously this will depend exactly on how your compiler works and you will need to test that the objects are getting placed in the correct positions (but this would be perfect place to learn about TDD.

4
ответ дан 5 December 2019 в 06:54
поделиться

Depends. If you use bit fields, then you let the compiler worry about how to store the data (bitfields are pretty much completely implementation-defined), which means that:

  • It might use more space than necessary, and
  • Accessing each member will be done efficiently.

The compiler will typically organize the layout of the struct so that the second assumption holds, at the cost of total size of the struct.

The compiler will probably insert padding between each member, to ease access to each field.

On the other hand, if you just store everything in a single unsigned long (or an array of chars), then it's up to you to implement efficient access, but you have a guarantee of the layout. It will take up a fixed size, and there will be no padding. And that means that copying the value around may get less expensive. And it'll be more portable (assuming you use a fixed-size int type instead of just unsigned int).

0
ответ дан 5 December 2019 в 06:54
поделиться

Компилятор может иногда комбинировать доступ к битовым полям не интуитивно понятно. Однажды я разобрал сгенерированный код (gcc 3.4.6 для sparc) при доступе к 1-битным записям, которые использовались в условных выражениях. Компилятор объединил доступ к битам и произвел сравнение с целыми числами. Я попытаюсь воспроизвести идею (не на работе и не могу получить доступ к исходному коду, который был задействован):

struct bits {
  int b1:1;
  int b2:1;
  int b3:1;
  ...
} x;

if(x.b1 && x.b2 && !x.b3)
...
if(x.b2 && !x.b2 && x.b3)

был скомпилирован во что-то эквивалентное (я знаю, что битордер в моем примере противоположный, но это только ради из упрощения примера).

temp = (x & 7);
if( temp == 6)
...
if( temp == 5)

Есть еще один момент, который следует учитывать, если кто-то хочет использовать битовые поля (они часто более читабельны, чем бит-кунг-фу), если у вас есть запасные биты, может быть полезно зарезервировать целые байты для определенных полей, что упрощает доступ для процессора. Выровненное 8-битное поле может быть загружено с помощью команды перемещения байта и не требует шага маскирования.

0
ответ дан 5 December 2019 в 06:54
поделиться

Only if your architecture explicitly has a set of instructions for bit-wise manipulation and access.

1
ответ дан 5 December 2019 в 06:54
поделиться

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

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

4
ответ дан 5 December 2019 в 06:54
поделиться