Generate bitmask from 16 byte fields using SSE [duplicate] - sse

This question already has answers here:
How to create a 8 bit mask from lsb of __m64 value?
(2 answers)
Extract the low bit of each bool byte in a __m128i? bool array to packed bitmap
(2 answers)
Closed 3 years ago.
After some operations I have an SSE register where each of the 16 bytes has the lowest bit set if some condition was fulfilled or it is 0 if it wasn't. I'd now would like to extract this into a bitmask where for each of these 16 bytes a bit is set iff the byte had value one.
I searched the Intel intrinsics guide up and down but couldn't really find how to do this. Pseudocode
void _mm_???(__m128i a)
FOR j := 0 to 15
i := j*8
IF a[i]
a[j] := 1
else
a[j] := 0
FI
ENDFOR

Related

Get Integer number from a Float?

I Have a number that is divided by 12 Months.
I need to get the result of the division as an Integer number.
Ex:
mTblDetailMonth.FieldByName('Target_').asfloat := (MTblDetail.FieldByName('Target_').AsInteger / 12 );
When the MTblDetail.FieldByName('Target_').AsInteger is equal to 20 and divide
20 / 12, the Result is 1.666666667.
I need to get the number 1 only and then calculate the floating decimal number.
Your question is not very clear, so here's two alternatives:
The answer to your question as it is written (assuming an integer variable years and a float variable remainder)
use trunc to get the integer part of the division result
years := trunc(MTblDetail.FieldByName('Target_').AsInteger / 12); // returns 1
remainder := MTblDetail.FieldByName('Target_').AsInteger / 12 - years; // returns 0.6666...
Since you talk about months, maybe you want to know 'years' and 'months' as integers.
If so, use div and mod operators:
years := MTblDetail.FieldByName('Target_').AsInteger div 12 ; // returns 1
months := MTblDetail.FieldByName('Target_').AsInteger mod 12 ; // returns 8

Enumeration set size in x64

I found that a SizeOf(set) i different in 32-bit and 64-bit, the example below shows 5 byte for 32-bit and 8 for 64-bit. But i found nothing information about changes in SizeOf(sets) for 64-bit. Is there any Embarcadero documentation about it or compiler directive to get a similar results on 32 and 64-bit.
program Project1;
{$APPTYPE CONSOLE}
{$R *.res}
uses System.SysUtils;
type
{ Enumeration of properties}
TProperty1 = (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14,
p15, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25, p26, p27, p28,
p29, p30, p31, p32, p33, p34, p35, p36, p37);
TProperties1 = set of TProperty1;
begin
WriteLn(SizeOf(TProperties1));
ReadLn;
end.
To answer your question. I couldn't find anything on the Embarcadero site regarding the differences or a compiler directive to change the behavior. My research indicates the following:
Sets have the following sizes in bytes in 32 bit:
Up to 8 elements - 1 Byte
9 to 16 elements - 2 Bytes
17 to 32 elements - 4 Bytes
From this point onwards it adds adds bytes as needed, one at a time. So 33 to 40 elements uses 5 bytes and 41 to 48 elements uses 6 bytes.
In 64 bit mode, things are slightly different:
Up to 8 elements - 1 Byte
9 to 16 elements - 2 Bytes
17 to 32 elements - 4 Bytes
33 to 64 elements - 8 Bytes
From this point onwards it adds adds bytes as needed, one at a time. So 65 to 72 elements uses 9 bytes and 73 to 80 elements uses 10 bytes.
To get around this you are going to need to either use something like WriteSet in TWriter.WriteProperty and TReader.ReadSet or you can do something like this:
procedure SaveSetToStream(aStream: TStream; const aSet: TProperties1);
var
streamData: array[0..7] of byte;
begin
Assert(SizeOf(aSet) <= SizeOf(streamData), 'Set is too large to save. Increase the array length.');
FillChar(streamData, SizeOf(streamData), 0);
Move(aSet, streamData, SizeOf(aSet));
aStream.Write(streamData, SizeOf(streamData));
end;
function ReadFromStream(aStream: TStream): TProperties1;
var
streamData: array[0..7] of byte;
begin
Assert(SizeOf(Result) <= SizeOf(streamData), 'Set is too large to load. Increase the array length.');
aStream.Read(streamData, SizeOf(streamData));
Move(streamData, Result, SizeOf(Result));
end;
Another workaround, to make sure a 32 bit machine can read a stream from a 64 bit machine and vice-versa is to create a function
function SizeCheck( const p : integer ) : integer;
begin
if p in [5..8 ] then Result := 8 else Result := p; // adjust for 64 bit set sizes
end;
and then use
Stream.Write(set, SizeCheck(SizeOf(set)));
Obviously only use for sets.

Why doesn't "i := i + 1" give a range-check error for Integers and larger types?

Consider:
{$R+}
i:= 1;
While i > 0 do
i:= i + 1;
ShowMessage(IntToStr(i));
If I declare i as Byte, Word, Shortint or TinyInt I get a range-check error, as expected.
If I declare i as LongWord, Cardinal, Integer, LongInt or Int64 it just goes through the while loop and gets to show the negative or 0 value, which i gets when you pass the upper bound.
Does Delphi 7 not support range checking for 32-bit and 64-bit numbers?
The operation i + 1 doesn't actually produce a range check error. The assignment operation does.
Delphi evaluates the constant '1' as an Integer and so the right hand side will produce a result that is either an Int64 or an Integer (The larger of i's type and Integer).
If we expand the line out we get the following
temp := i + 1
i := temp
temp will either be 32 or 64 bits, and will overflow if it hits the upper bound. By the time we do the assignment, we have a perfectly valid 32 or 64bit value so there's no possibility of a range check failure if i is 32bits or more.
If i is less than 32 bits, it will raise a range check if temp is too large to fit.
For i >= 32bits, you can catch the overflow error like so:
{$R+,Q+}
...

How can I get a result larger than 2^32 from shl?

Declaration...
const
n = 2 shl 33
will set constant n to value 4 without any compiler complaint!
Also...
Caption := IntToStr(2 shl 33);
...return 4 instead 8589934592.
It looks like the compiler calculates like this:
2 shl 33 = 2 shl (33 and $1F) = 4
But without any warning or overflow.
The problem remains if we declare:
const
n: int64 = 2 shl 33;
The number in constant is still 4 instead 8589934592.
Any reasonable work around?
You're looking for the wrong results, according to both the Delphi compiler and Windows 7's calculator in programmer mode. (The answer you're wanting is actually 2 shl 32, BTW.)
You need to cast both sides of the shl to Int64:
const
n = Int64(2) shl Int64(33);
This produces
N = 17179869184;
The current documentation (for XE2, but applies to earlier versions of Delphi as well) notes this in Fundamental Integer Types. However, that page mentions only having to cast one of the operands as Int64; my test shows it to require both operands be typecast in the const declaration above - typecasting only one (regardless of which one) also resulted in `n = 4;'.

What is the meaning of the internet connection statuses?

What is the meaning of the internet connection statuses?
I can't figure out which status represents a router, number 3?
What does 4 mean?
uses
WinInet;
const
MODEM = 1;
LAN = 2;
PROXY = 4;
BUSY = 8;
function GetConnectionKind(var strKind: string): Boolean;
var
flags: DWORD;
begin
strKind := '';
Result := InternetGetConnectedState(#flags, 0);
if Result then
begin
if (flags and MODEM) = MODEM then strKind := 'Modem';
if (flags and LAN) = LAN then strKind := 'LAN';
if (flags and PROXY) = PROXY then strKind := 'Proxy';
if (flags and BUSY) = BUSY then strKind := 'Modem Busy';
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
strKind: string;
begin
if GetConnectionKind(strKind) then
ShowMessage(strKind);
end;
[InternetGetConnectedState](http://msdn.microsoft.com/en-us/library/aa384702(VS.85%29.aspx) returns a bitmask in the first parameter that looks like this:
76543210 <-- bit numbers
|| ||||
|| |||+- INTERNET_CONNECTION_MODEM
|| ||+-- INTERNET_CONNECTION_LAN
|| |+--- INTERNET_CONNECTION_PROXY
|| +---- INTERNET_CONNECTION_MODEM_BUSY (No longer used)
|+------ INTERNET_CONNECTION_OFFLINE
+------- INTERNET_CONNECTION_CONFIGURED
If a given bit is set, the connection is of that type. So if bit nr. 2 is set, you're connected through a proxy.
Additionally, the function returns a TRUE/FALSE value, indicating whether you are connected to the internet.
The values you have in your code, 1, 2, 4, 8, corresponds to the decimal value of those bits, counting from the right.
Basically the code inspects each bit in turn, and sets the strKind variable to a text indicating the nature of the connection.
You're asking "which is router? 3?", and I assume you mean by that "how do I figure out that my connection is through a router?". I would assume this would be the same as the LAN connection, presumably the LAN has a bridge somewhere to access the internet through.
The codes 1, 2, 4, 8 represent bitmasks. I generally prefer to always use bitmasks in hex to avoid any confusion, its fairly easy to remember since the pattern continues in nibbles (the set of 4 binary bits).
HEX BINARY DEC
$01 00000001 1
$02 00000010 2
$04 00000100 4
$08 00001000 8
$10 00010000 16
$20 00100000 32
$40 01000000 64
$80 10000000 128
If you ever want to check two values at once, you can OR them together, for example $01 or $02 = $03 (binary 00000011). So a 3 would be BOTH a modem AND a lan.
A common practice to see if something is set or not, would be to AND it with the mask. for example, if my number is 3, and i "and" this with $02, then the result is $02 since the bit for both the mask AND the value were both set. If my number is 4 and I "and" this with $02, then the result is $00 since the bit for both the mask and the value were not set.
Of course this doesn't answer what I think your real question is. The router would be impossible to determine just by checking only this mask. This mask just tells you if your connected via a modem (aka Dialup) or a network adapter. The router would be beyond the network adapter, and would require further analysis of the network to accurately determine.
The constant values are flags which means two things: (1) you cannot have a "3" value and (2) you can have more than one value in the "flags" result. For example, for result 9 (1001 in binary) the first and last checks would be true.
For more info on the result meaning check the MSDN reference for InternetGetConnectedState.

Resources