简体   繁体   中英

Type cast char array[16] to int 128 bits

I have two 16bytes char array:

char word[WORD_LENGTH] = { '1', '2', '3', '4', '5', '6','7','8','9','0','1','2','3','4','5','\0'};
char word2[WORD_LENGTH] = { '1', '2', '3', '4', '5', '6','7','8','9','0','1','2','3','4','5','\0'};

I'm looking for a way to compare two char arrays faster than compare character by character would be. From my knowledge, I think that I can convert char array into 128 int using type casting; like this

__int128 value = (__int128) word;
__int128 value2 = (__int128) word2;

But these doesn't work, because value and value2 contains the address of word and word2.

How I convert char array into __int128?

I would just use memcmp.

Are you sure that the compiler you are using is gonna then compare the int128 in some special part of the cpu where 128integers can be compared togheter? Because if it splits in 32 bit pars it will be useless.

int memcmp(word, word2, 16)

If you are looking for the extreme performance case, you have to compare the ASM derived from different implementation of this logic

Consider also that 128bit math is in the domain of mmx or sse or avx. As far as ai know, those are meant to be used on multiple set of data togheter, i don't think that using them for a single compare is usefull in terms of speed gain.

if it would be usefull in term of performance i bet that gcc, icc and other c compiler would do this 128bit, 256bit comparing as an internal optimization of memcmp more than leaving the idea to the user.

尝试

__int128 value = *(__int128 *)word;

NOTE: You're asking about two languages, and don't indicate which you're actually using. I'll try to answer for both, but my knowledge of C is some years out of date, so I might get some details wrong there.

There are several options; you'll have to measure them to determine which is fastest in your environment.

A good implementation of std::equal (in C++) or memcmp (in C) might be optimised for small arrays of known size. That might be good enough.

The only well-defined way to reinterpret the bytes as another type is to copy them:

__int128 value;
copy(begin(word), end(word), reinterpret_cast<char*>(&value));  // C++
memcpy((char*)(&value), word, WORD_SIZE)                        // C

The compiler might or might not optimise this to load words rather than bytes.

If all else fails, you can resort to formally undefined behaviour:

__int128 value = *reinterpret_cast<__int128*>(word); // *(__int128*)word in C

On some platforms, this might fail if the arrays aren't suitably aligned, or for other reasons.

Use the standard comparison function memcmp , and let the compiler worry about optimising your code:

memcmp(word, word2, WORD_LENGTH)

If after profiling you find that this is not fast enough for you, you can worry about improving that (eg by using a union, or by using SSE2 intrinsics) — but you will most likely find it difficult to beat a good implementation of memcmp.

You should use a pointer to __int128.

I tried it with __int64 type (my MSVC doesn`t support __int128) and it worked fine:

__int64 *value = (__int64*) word;
__int64 *value2 = (__int64*) word2;

Note that word[0] will be low-significant byte in value, so comparing will 'begin' with word[15].

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM