Скорость получения байта по указателю
От: WinterMute Россия http://yarrr.ru
Дата: 06.09.04 16:49
Оценка:
Допустим, у меня есть указатель на 32-х битное целое, нужно получить в нём второй байт, какой код будет быстрее:

int* pInt = ....;

BYTE second = ((byte*)pInt)[1];
или 
BYTE second = (*pInt & 0x00ff0000) >> 16;

// И что быстрее, если мне нужно разложить по байтам всё целое число?

BYTE first  = ((byte*)pInt)[0];
BYTE second = ((byte*)pInt)[1];
BYTE third  = ((byte*)pInt)[2];
BYTE fourth = ((byte*)pInt)[3];

или 

BYTE first  = (*pInt & 0xff000000) >> 24;
BYTE second = (*pInt & 0x00ff0000) >> 16;
BYTE third  = (*pInt & 0x0000ff00) >> 8;
BYTE fourth = (*pInt & 0x000000ff);
... << RSDN@Home 1.1.4 @@subversion >>
Re: Скорость получения байта по указателю
От: JakeS  
Дата: 06.09.04 17:26
Оценка:
46:       BYTE second1 = ((byte*)pInt)[1];
00402A08   mov         eax,dword ptr [ebp-14h]
00402A0B   mov         cl,byte ptr [eax+1]
00402A0E   mov         byte ptr [ebp-18h],cl
47:       BYTE second2 = (*pInt & 0x00ff0000) >> 16;
00402A11   mov         edx,dword ptr [ebp-14h]
00402A14   mov         eax,dword ptr [edx]
00402A16   and         eax,0FF0000h
00402A1B   shr         eax,10h
00402A1E   mov         byte ptr [ebp-1Ch],al


думаю ясно без слов.
Re[2]: Скорость получения байта по указателю
От: WinterMute Россия http://yarrr.ru
Дата: 06.09.04 17:52
Оценка:
JS>
JS>46:       BYTE second1 = ((byte*)pInt)[1];
JS>00402A08   mov         eax,dword ptr [ebp-14h]
JS>00402A0B   mov         cl,byte ptr [eax+1]
JS>00402A0E   mov         byte ptr [ebp-18h],cl
JS>47:       BYTE second2 = (*pInt & 0x00ff0000) >> 16;
JS>00402A11   mov         edx,dword ptr [ebp-14h]
JS>00402A14   mov         eax,dword ptr [edx]
JS>00402A16   and         eax,0FF0000h
JS>00402A1B   shr         eax,10h
JS>00402A1E   mov         byte ptr [ebp-1Ch],al
JS>


JS>думаю ясно без слов.


Вроде ведь mov mov'у рознь, т.е. в зависимости от аргументов будут выполняться разные команды. Тут я вижу только что в первом случае код на ассемблере короче, что не гарантирует более быстрого выполнения.

Или нет? Я ассемблер почти не знаю.
... << RSDN@Home 1.1.4 @@subversion >>
Re: Скорость получения байта по указателю
От: _nn_ www.nemerleweb.com
Дата: 06.09.04 18:02
Оценка:
Здравствуйте, WinterMute, Вы писали:

Может сделать так :
union int_char
{
 int i;
 char c[4];
};

int_char* ic = pInt;
// Доступ
ic.c[0]
ic.c[1]
ic.c[2]
ic.c[3]


P.S.
Под Windows будет работать, но корректная работа не гарантированна стандартом.
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[2]: Скорость получения байта по указателю
От: WinterMute Россия http://yarrr.ru
Дата: 06.09.04 18:16
Оценка:
Здравствуйте, _nn_, Вы писали:

__>Может сделать так :

__>
__>union int_char
__>{
__> int i;
__> char c[4];
__>};

__>int_char* ic = pInt;
__>// Доступ
__>ic.c[0]
__>ic.c[1]
__>ic.c[2]
__>ic.c[3]
__>


Но сначала-то у меня указатель на int, т.е., придётся или копировать содержимое в эту структуру, или приводить указатели, что в общем я и делал, только с байтами. В итоге выйгрыш будет только в удобстве, но не в скорости.
... << RSDN@Home 1.1.4 @@subversion >>
Re[3]: Скорость получения байта по указателю
От: _nn_ www.nemerleweb.com
Дата: 06.09.04 18:22
Оценка:
Здравствуйте, WinterMute, Вы писали:

WM>Здравствуйте, _nn_, Вы писали:


__>>Может сделать так :

__>>
__>>union int_char
__>>{
__>> int i;
__>> char c[4];
__>>};

__>>int_char* ic = pInt;
__>>// Доступ
__>>ic.c[0]
__>>ic.c[1]
__>>ic.c[2]
__>>ic.c[3]
__>>


WM>Но сначала-то у меня указатель на int, т.е., придётся или копировать содержимое в эту структуру, или приводить указатели, что в общем я и делал, только с байтами. В итоге выйгрыш будет только в удобстве, но не в скорости.


А в чем проблема :
void x(int* p)
{
 ((int_char*)p)->c[0];
 // или
 int_char* pic = (int_char*)p;
 pic->c[0];
}
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[4]: Скорость получения байта по указателю
От: WinterMute Россия http://yarrr.ru
Дата: 06.09.04 18:28
Оценка:
__>А в чем проблема :
__>
__>void x(int* p)
__>{
__> ((int_char*)p)->c[0];
__> // или
__> int_char* pic = (int_char*)p;
 pic->>c[0];
__>}
__>


Проблемы нет, просто где тут выйгрыш в скорости по сравнению с:
>void x(int* p)
>{
> BYTE b = ((byte*)p)[0];
>}
... << RSDN@Home 1.1.4 @@subversion >>
Re: Скорость получения байта по указателю
От: Шахтер Интернет  
Дата: 06.09.04 18:56
Оценка:
Здравствуйте, WinterMute, Вы писали:

WM>Допустим, у меня есть указатель на 32-х битное целое, нужно получить в нём второй байт, какой код будет быстрее:


WM>
WM>int* pInt = ....;

WM>BYTE second = ((byte*)pInt)[1];
WM>или 
WM>BYTE second = (*pInt & 0x00ff0000) >> 16;

WM>// И что быстрее, если мне нужно разложить по байтам всё целое число?

WM>BYTE first  = ((byte*)pInt)[0];
WM>BYTE second = ((byte*)pInt)[1];
WM>BYTE third  = ((byte*)pInt)[2];
WM>BYTE fourth = ((byte*)pInt)[3];

WM>или 

WM>BYTE first  = (*pInt & 0xff000000) >> 24;
WM>BYTE second = (*pInt & 0x00ff0000) >> 16;
WM>BYTE third  = (*pInt & 0x0000ff00) >> 8;
WM>BYTE fourth = (*pInt & 0x000000ff);
WM>


Второй вариант правильный. Первый будет работать только на некоторых платформах. Насчет скорости сказать ничего нельзя. Хотя при большом регистровом пространстве второй вариант может оказаться быстрее.
... << RSDN@Home 1.1.0 stable >>
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Re[2]: Скорость получения байта по указателю
От: JakeS  
Дата: 07.09.04 05:07
Оценка:
господа, елси уж для вашей программы существенна разница в скорости выполнения команды mov — Пишите нужный участок в чистом ассемблере, однозначно будет быстрее.
Re[3]: Скорость получения байта по указателю
От: WinterMute Россия http://yarrr.ru
Дата: 07.09.04 06:36
Оценка:
JS>господа, елси уж для вашей программы существенна разница в скорости выполнения команды mov — Пишите нужный участок в чистом ассемблере, однозначно будет быстрее.

Но я не знаю ассемблера
... << RSDN@Home 1.1.4 @@subversion >>
Re[2]: Скорость получения байта по указателю
От: Sir Wiz Россия  
Дата: 07.09.04 07:32
Оценка:
Здравствуйте, Шахтер, Вы писали:


WM>>
WM>>int* pInt = ....;

// Кусь

WM>>BYTE first  = (*pInt & 0xff000000) >> 24;
WM>>BYTE second = (*pInt & 0x00ff0000) >> 16;
WM>>BYTE third  = (*pInt & 0x0000ff00) >> 8;
WM>>BYTE fourth = (*pInt & 0x000000ff);
WM>>


Ш>Второй вариант правильный. Первый будет работать только на некоторых платформах.


Нет, второй вариант тоже неправильный. Правый сдвиг отрицательных чисел определяется реализацией компилятора.
Кроме того не гарантируется, что размер типа int будет равен 4-м байтам.
... << RSDN@Home 1.1.4 @@subversion >>
Re[3]: Скорость получения байта по указателю
От: Sir Wiz Россия  
Дата: 07.09.04 07:33
Оценка:
Здравствуйте, JakeS, Вы писали:

JS>господа, елси уж для вашей программы существенна разница в скорости выполнения команды mov — Пишите нужный участок в чистом ассемблере, однозначно будет быстрее.


Как правило интеловский, например, компилятор генерирует более качественный код. Так как учитывает особенности работы процессора.
... << RSDN@Home 1.1.4 @@subversion >>
Re[4]: Скорость получения байта по указателю
От: JakeS  
Дата: 07.09.04 08:36
Оценка:
Здравствуйте, Sir Wiz, Вы писали:

SW>Здравствуйте, JakeS, Вы писали:


JS>>господа, елси уж для вашей программы существенна разница в скорости выполнения команды mov — Пишите нужный участок в чистом ассемблере, однозначно будет быстрее.


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


В данном случае никакие особенности процессора ни при чем. речь идет всего лишь о доступе к участкам памяти. Очевидно что быстрее всего единственная операция mov регистр, адрес и в дальнейшем работа только с регистрами. Причем совершенно без разницы какой процессор.
mov eax, addr
mov ebx
а затем получение и сразу же использование байтиков, типа:
mov eax, ebx
shr eax, 16
and eax, FFh
но ни один компиллятор такого не сделает, ибо все зависит от конкретного случая, а компиллятору это до фонаря. Поэтому повторяю, если это действительно критично — inline asm. Иначе не стоит парится о таких мелочах а оптимизировать чтонибудь другое.
Re[3]: Скорость получения байта по указателю
От: elcste  
Дата: 07.09.04 09:18
Оценка:
Здравствуйте, Sir Wiz, Вы писали:

WM>>>int* pInt = ....;

SW>// Кусь

WM>>>BYTE first  = (*pInt & 0xff000000) >> 24;
WM>>>BYTE second = (*pInt & 0x00ff0000) >> 16;
WM>>>BYTE third  = (*pInt & 0x0000ff00) >> 8;
WM>>>BYTE fourth = (*pInt & 0x000000ff);

Ш>>Второй вариант правильный. Первый будет работать только на некоторых платформах.

А почему, кстати?

SW>Нет, второй вариант тоже неправильный. Правый сдвиг отрицательных чисел определяется реализацией компилятора.


В приведенном выше коде — surprise! — никогда не будет правого сдвига отрицательных чисел.

SW>Кроме того не гарантируется, что размер типа int будет равен 4-м байтам.


Это да. Но тогда и задача разложить int на черыре байта выглядит как-то...
Re[3]: Скорость получения байта по указателю
От: WinterMute Россия http://yarrr.ru
Дата: 07.09.04 09:26
Оценка:
WM>>>BYTE first = (*pInt & 0xff000000) >> 24;
WM>>>BYTE second = (*pInt & 0x00ff0000) >> 16;
WM>>>BYTE third = (*pInt & 0x0000ff00) >> 8;
WM>>>BYTE fourth = (*pInt & 0x000000ff);
WM>>>[/ccode]

Ш>>Второй вариант правильный. Первый будет работать только на некоторых платформах.


SW>Нет, второй вариант тоже неправильный. Правый сдвиг отрицательных чисел определяется реализацией компилятора.


int я привёл для примера, у меня, конечно, unsigned int

SW>Кроме того не гарантируется, что размер типа int будет равен 4-м байтам.


Меня интересовало как будет быстрее, все попутные проблемы в общем не суть.
... << RSDN@Home 1.1.4 @@subversion >>
Re[4]: Скорость получения байта по указателю
От: Sir Wiz Россия  
Дата: 07.09.04 09:29
Оценка:
Здравствуйте, elcste, Вы писали:

SW>>Нет, второй вариант тоже неправильный. Правый сдвиг отрицательных чисел определяется реализацией компилятора.


E>В приведенном выше коде — surprise! — никогда не будет правого сдвига отрицательных чисел.


(*pInt & 0xff000000) >> 24;


Не будет, говорите? Это для x86. Borland и VC сделают тут две разные вещи.

А ещё есть вариации с low/big endian... Я не нашел в стандарте ни слова о требованиях к побитному расположению в памяти интегральных типов.
... << RSDN@Home 1.1.4 @@subversion >>
Re[5]: Скорость получения байта по указателю
От: Sir Wiz Россия  
Дата: 07.09.04 09:31
Оценка:
Здравствуйте, JakeS, Вы писали:

JS>>>господа, елси уж для вашей программы существенна разница в скорости выполнения команды mov — Пишите нужный участок в чистом ассемблере, однозначно будет быстрее.


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


JS>В данном случае никакие особенности процессора ни при чем. речь идет всего лишь о доступе к участкам памяти. Очевидно что быстрее всего единственная операция mov регистр, адрес и в дальнейшем работа только с регистрами. Причем совершенно без разницы какой процессор.


Не претендую на профессианлизм в этом вопросе, но как же конвейерная оптимизация?
... << RSDN@Home 1.1.4 @@subversion >>
Re[4]: Скорость получения байта по указателю
От: Sir Wiz Россия  
Дата: 07.09.04 09:35
Оценка:
Здравствуйте, WinterMute, Вы писали:

WM>Меня интересовало как будет быстрее, все попутные проблемы в общем не суть.


Правильно
Автор: JakeS
Дата: 06.09.04
, ИМХО.
... << RSDN@Home 1.1.4 @@subversion >>
Re[4]: Скорость получения байта по указателю
От: Sir Wiz Россия  
Дата: 07.09.04 09:39
Оценка:
Здравствуйте, elcste, Вы писали:

Ш>>>Второй вариант правильный. Первый будет работать только на некоторых платформах.

E>А почему, кстати?

Например, отсутствие физической возможности обратиться к адресу не кратному 2^n, где n > 0.
... << RSDN@Home 1.1.4 @@subversion >>
Кстати да
От: WinterMute Россия http://yarrr.ru
Дата: 07.09.04 09:43
Оценка:
WM>>Меня интересовало как будет быстрее, все попутные проблемы в общем не суть.

SW>Правильно
Автор: JakeS
Дата: 06.09.04
, ИМХО.


Опыт показал что способ с преобразованием к указателю на байт вроде как быстрее (примерно на 20-30%%). Хотя подозреваю что результат может измениться при использовании разных компиляторов и оптимизаций под отдельные процессоры. (Я компилировал на штатном VC с включением оптимизации по скорости).
... << RSDN@Home 1.1.4 @@subversion >>
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.