memcpy() и int'ы
например есть два числа:
int int0 = 0x1234FFFF;
int int1 = 0x1234FFFF;
как-нть можно скопировать 2 младших байта int1 в 2 старших байта int0 ?
(чтобы получить int0 = 0xFFFFFFFF)
p.s. требуется именно копирование (важна скорость), а не другие подобные способы типа такого:
int0&=0x0000FFFF;
// сдвигаем и одновременно затираем младшие 2 байта
int1<<=16; (стало 0xFFFF0000)
// "копируем"
int0|=int1;
p.p.s кстати, какая операция занимает больше процессорного времени? XOR (^=) или OR (|=) ?
#include <stdlib.h>
#include <string.h>
#define bitcpy(dest,src,type) \
memcpy( \
(((char*)&dest)+(sizeof(type)>>1)), \
&src,(sizeof(type)>>1) \
)
int main() {
int x=0x12345678;
int y=0x87654321;
bitcpy(x,y,int);
printf("0x%X\n",x); // выводит 0x43215678
return 0;
}
Первые два параметра макроса обязательно переменные одного типа, третий - тип этих переменных.
Размер переменной этого типа должен быть кратен двум
ЗЫ: |= это не AND а OR
ЗЗЫЫ: Считаю, что битовые операции будут работать быстрее, так как в моем варианте присутсвует вызов функции
например есть два числа:
int int0 = 0x1234FFFF;
int int1 = 0x1234FFFF;
как-нть можно скопировать 2 младших байта int1 в 2 старших байта int0 ?
(чтобы получить int0 = 0xFFFFFFFF)
но это не очень хорошо с т.з. языка т.к.:
1) взятие адреса усложняет оптимизацию,
2) код становится зависимым от процессора (little-endian).
Впрочем, переход little <-> big endian всегда болезненный, но при таком решении он более гибкий, чем при сдвигах, т.к. при сдвиге придется менять операцию, а при таком решении лишь индексы.
Накладываешь необходимую тебе битовую маску и получаешь необходимый результат, а затем копируешь, вставляешь да и что хочешь - то и творишь. Получиться не так элегантно как многим хочется, но быстрее и не получиться :)
В Unix для подобных целей сущуствуют, если так можно назвать, "ассемблерные" макро-определения или шаблоны.
Накладываешь необходимую тебе битовую маску и получаешь необходимый результат, а затем копируешь, вставляешь да и что хочешь - то и творишь. Получиться не так элегантно как многим хочется, но быстрее и не получиться :)
В Unix для подобных целей сущуствуют, если так можно назвать, "ассемблерные" макро-определения или шаблоны.
Что-то я не совсем понял, какое отношение встроеный ассемблер имеет к битовым маскам..
При чем тут, в контексте задачи, встроенный ассемблер применительно к битовым маскам?
Это можно сделать и без ассемблера, и с точно такоё же скоростью (раз уж ты о ней так печешься).
А уж при копировании байтов битовые маски вовсе не нужны.
При чем тут, в контексте задачи, встроенный ассемблер применительно к битовым маскам?[/quote]
А почему бы и нет?
[QUOTE=Green]Это можно сделать и без ассемблера, и с точно такоё же скоростью (раз уж ты о ней так печешься).[/QUOTE]
А помоему "печется" topic starter
[QUOTE=Аццкий программер]p.s. требуется именно копирование (важна скорость), а не другие подобные способы типа такого:[/QUOTE]
[QUOTE=Green]А уж при копировании байтов битовые маски вовсе не нужны. [/QUOTE]
При полном копировании байтов - конечно же нет. Дак вот.....
[QUOTE=Аццкий программер]Есть ли какой-нть способ копировать произвольные разряды памяти int'ов(longов, floatов, __int64 и пр.)?[/QUOTE]
При произвольном, или я бы назвал выборочном копировании разрядов байта, битовые маски пригодились бы. А уж как это сделать - думаю стоит оставить принятие решения все же за конечным программистом. Ты ж не осудишь меня за исользование ассемблера?
Хороший подход к написанию программ. Вы все подключаете по принципу "а почему бы и нет"?
обе выполняются за один такт
Впрочем, переход little <-> big endian всегда болезненный, но при таком решении он более гибкий, чем при сдвигах, т.к. при сдвиге придется менять операцию, а при таком решении лишь индексы.
Ты об этом?
int0&=0x0000FFFF;
// сдвигаем и одновременно затираем младшие 2 байта
int1<<=16; (стало 0xFFFF0000)
// "копируем"
int0|=int1;
Автор, тебя реально уже имеющаяся скорость не устраевает?
Блин, всегда думал, что такой код гарантирует один результат на всех компьютерах, для которых его можно скомпилировать (ну и sizeof(int) >= 4)... И в исходниках криптосистем используют именно сдвиги и операции над двоичными множествами, а не цирк с адресами и смещениями. Не разбивай мне сердце... :)
Хм... здесь может быть погорячился.
С т.з. ЯВУ сдвиг все же должен происходить одинаково и независимо от индейцев.
А на счет цирка... это не цирк, это низкоуровневая оптимизация.
это новость меня порадовала) пишу как раз подобие этого.
В данный момент пытаюсь создать RSA систему шифрования. Скорость важна не потому, что она претендует на роль "очень удачной реализации", а скорее наоборот, все работает ОЧЕНЬ медленно. Сейчас выполнение шифрования/дешифрования занимает очень много времени. Занимаюсь опитимизацией. А по введенному мной подсчету числа вызовов функций опреций получил нечто вроде 100 тысяч операций сдвигов(влево/вправо примерно поровну) на 2.7 тысяч операций умножения. Соответственно, решил попробовать оптимизировать для начала сдвиги, потом искать прочие ляпы в коде.
т.е. лучше оставить все подобные операции в их реализации сдвигами?
это место :)
т.е. что же мне в конечном счете делать лучше? :confused:
пока я не увидел ни одного четкого ответа на свой вопрос, кроме ответа Green
Лучше действовать профессионально, а не методом научного тыка.
Для начала получить профайл и выявить узкие места. Оптимизировать их на алгоритмическом уровне, на уровне реализации, а уж затем заниматься низкоуровневой оптимизацией.
скачал AQ Time, нефига не понял как им пользоваться :)
в общем, использую вместо профайлера _ftime64() :)
"пережеванные" функциями результаты записываю в файл и перекручиваю этот же файл через наскоро сделанную на java утилитку проверяющую этот файл на "праильность" (java.math.BigInteger) - очень даже ниче получается. че-то я сразу до такого не додумался(
за вечер переписал большую часть кода с нуля (рефакторинг прошлого проекта невозможен - настока там все загнило :(
много чего поправил, теперь все летает почти! спс всем!!
memcpy(&int1,&int0+2,2);
memcpy(&int1,&int0+2,2);
Ну и зря.
Про сдвиги - чепуха.
Сдвиг - платформо-независимая операция. В частности, именно поэтому во многих переносимых форматах файлов, более чем обнобайтные данные дампятся и поднимаются из дампов побайтно, со сдвигами.
Сдвиг - платформо-независимая операция. В частности, именно поэтому во многих переносимых форматах файлов, более чем обнобайтные данные дампятся и поднимаются из дампов побайтно, со сдвигами.
Ещё раз, с добрым утром.
Уже обсудили. Читаем внимательнее.