www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - start on SIMD documentation

reply Walter Bright <newshound2 digitalmars.com> writes:
https://github.com/D-Programming-Language/d-programming-language.org/blob/master/simd.dd

and core.simd:

https://github.com/D-Programming-Language/druntime/blob/master/src/core/simd.d
Jan 13 2012
next sibling parent reply Peter Alexander <peter.alexander.au gmail.com> writes:
On 13/01/12 8:39 AM, Walter Bright wrote:
 https://github.com/D-Programming-Language/d-programming-language.org/blob/master/simd.dd


 and core.simd:

 https://github.com/D-Programming-Language/druntime/blob/master/src/core/simd.d
Nice! Although... import core.simd; void main() { float4 a = void; // float a; doesn't work either a = simd(XMM.PXOR, a); } *** Internal error: backend/cgcod.c 2048 *** Are all those instructions implemented? I seem to get the same for all instructions. Also, slight bikeshedding issue: I'm not so sure on using names like int4 for vectors. You see things like int32 a lot to mean a 32-bit integer, or int8 to mean an 8-bit integer. Using this notation for vectors may be confusing. As for what to change it to, I don't really care. int4v, vec_int4, int_vector4, anything. It doesn't matter.
Jan 13 2012
next sibling parent Peter Alexander <peter.alexander.au gmail.com> writes:
On 13/01/12 7:06 PM, Peter Alexander wrote:
 On 13/01/12 8:39 AM, Walter Bright wrote:
 https://github.com/D-Programming-Language/d-programming-language.org/blob/master/simd.dd



 and core.simd:

 https://github.com/D-Programming-Language/druntime/blob/master/src/core/simd.d
Nice! Although... import core.simd; void main() { float4 a = void; // float a; doesn't work either a = simd(XMM.PXOR, a); } *** Internal error: backend/cgcod.c 2048 *** Are all those instructions implemented? I seem to get the same for all instructions. Also, slight bikeshedding issue: I'm not so sure on using names like int4 for vectors. You see things like int32 a lot to mean a 32-bit integer, or int8 to mean an 8-bit integer. Using this notation for vectors may be confusing. As for what to change it to, I don't really care. int4v, vec_int4, int_vector4, anything. It doesn't matter.
Sorry, the code was meant to be: import core.simd; void main() { float4 a = void; a = simd(XMM.PXOR, a, a); } The error was for this code.
Jan 13 2012
prev sibling next sibling parent bearophile <bearophileHUGS lycos.com> writes:
Peter Alexander:

 I'm not so sure on using names like 
 int4 for vectors. You see things like int32 a lot to mean a 32-bit 
 integer, or int8 to mean an 8-bit integer. Using this notation for 
 vectors may be confusing.
 
 As for what to change it to, I don't really care. int4v, vec_int4, 
 int_vector4, anything. It doesn't matter.
It's not confusing for D programmers. But if you want to be on the safe side then int4v or vint4 sound acceptable. Bye, bearophile
Jan 13 2012
prev sibling next sibling parent reply Iain Buclaw <ibuclaw ubuntu.com> writes:
On 13 January 2012 19:06, Peter Alexander <peter.alexander.au gmail.com> wr=
ote:
 On 13/01/12 8:39 AM, Walter Bright wrote:
 https://github.com/D-Programming-Language/d-programming-language.org/blo=
b/master/simd.dd
 and core.simd:


 https://github.com/D-Programming-Language/druntime/blob/master/src/core/=
simd.d

 Nice!

 Although...

 import core.simd;
 void main()
 {
 =A0 =A0float4 a =3D void; // float a; doesn't work either
 =A0 =A0a =3D simd(XMM.PXOR, a);
 }

 *** Internal error: backend/cgcod.c 2048 ***

 Are all those instructions implemented? I seem to get the same for all
 instructions.

 Also, slight bikeshedding issue: I'm not so sure on using names like int4
 for vectors. You see things like int32 a lot to mean a 32-bit integer, or
 int8 to mean an 8-bit integer. Using this notation for vectors may be
 confusing.

 As for what to change it to, I don't really care. int4v, vec_int4,
 int_vector4, anything. It doesn't matter.
This is probably intelligable, but makes sense to me. Change int4 -> v4si Vector names that reflect the MODE they represent, rather than the TYPE. Regards --=20 Iain Buclaw *(p < e ? p++ : p) =3D (c & 0x0f) + '0';
Jan 13 2012
parent Walter Bright <newshound2 digitalmars.com> writes:
On 1/13/2012 11:18 AM, Iain Buclaw wrote:
 This is probably intelligable, but makes sense to me.

 Change   int4  ->   v4si
please, no!
 Vector names that reflect the MODE they represent, rather than the TYPE.
??
Jan 13 2012
prev sibling next sibling parent Iain Buclaw <ibuclaw ubuntu.com> writes:
On 13 January 2012 19:18, Iain Buclaw <ibuclaw ubuntu.com> wrote:
 On 13 January 2012 19:06, Peter Alexander <peter.alexander.au gmail.com> =
wrote:
 On 13/01/12 8:39 AM, Walter Bright wrote:
 https://github.com/D-Programming-Language/d-programming-language.org/bl=
ob/master/simd.dd
 and core.simd:


 https://github.com/D-Programming-Language/druntime/blob/master/src/core=
/simd.d

 Nice!

 Although...

 import core.simd;
 void main()
 {
 =A0 =A0float4 a =3D void; // float a; doesn't work either
 =A0 =A0a =3D simd(XMM.PXOR, a);
 }

 *** Internal error: backend/cgcod.c 2048 ***

 Are all those instructions implemented? I seem to get the same for all
 instructions.

 Also, slight bikeshedding issue: I'm not so sure on using names like int=
4
 for vectors. You see things like int32 a lot to mean a 32-bit integer, o=
r
 int8 to mean an 8-bit integer. Using this notation for vectors may be
 confusing.

 As for what to change it to, I don't really care. int4v, vec_int4,
 int_vector4, anything. It doesn't matter.
This is probably intelligable, but makes sense to me. Change =A0 int4 =A0-> =A0v4si Vector names that reflect the MODE they represent, rather than the TYPE.
Unintelligible, even... --=20 Iain Buclaw *(p < e ? p++ : p) =3D (c & 0x0f) + '0';
Jan 13 2012
prev sibling next sibling parent reply Manu <turkeyman gmail.com> writes:
On 13 January 2012 21:06, Peter Alexander <peter.alexander.au gmail.com>wrote:

 Also, slight bikeshedding issue: I'm not so sure on using names like int4
 for vectors. You see things like int32 a lot to mean a 32-bit integer, or
 int8 to mean an 8-bit integer. Using this notation for vectors may be
 confusing.
I had the same feeling. short8 really made me instanytly uncomfortable. I'm so used to seeing a number on the end of a trivial type as being the width in bits. Even though I knew exactly what I was looking at, I still unconsciously assumed this was an 8bit type... It makes perfect sense for float4, since it's completely absurd to imagine a 4bit float, and it's also conventional from Cg and HLSL. I wonder if there's a nice naming convention to mitigate this problem? Perhaps vshort8? Or some other small prefix/suffix?
Jan 13 2012
parent Peter Alexander <peter.alexander.au gmail.com> writes:
On 13/01/12 7:49 PM, Manu wrote:
 On 13 January 2012 21:06, Peter Alexander <peter.alexander.au gmail.com
 <mailto:peter.alexander.au gmail.com>> wrote:

     Also, slight bikeshedding issue: I'm not so sure on using names like
     int4 for vectors. You see things like int32 a lot to mean a 32-bit
     integer, or int8 to mean an 8-bit integer. Using this notation for
     vectors may be confusing.


 I had the same feeling.
 short8 really made me instanytly uncomfortable. I'm so used to seeing a
 number on the end of a trivial type as being the width in bits. Even
 though I knew exactly what I was looking at, I still unconsciously
 assumed this was an 8bit type...

 It makes perfect sense for float4, since it's completely absurd to
 imagine a 4bit float, and it's also conventional from Cg and HLSL.
 I wonder if there's a nice naming convention to mitigate this problem?
 Perhaps vshort8? Or some other small prefix/suffix?
Honestly, I be happy with any name as long as it was unambiguous. vshort8 short8v short8_v vec_short8 vec8_short short_vec8 short_v8 ... Anything will do. Just stick a v, vec, or vector somewhere and I'll be happy.
Jan 13 2012
prev sibling next sibling parent reply Mehrdad <wfunction hotmail.com> writes:
On 1/13/2012 11:06 AM, Peter Alexander wrote:
 On 13/01/12 8:39 AM, Walter Bright wrote:
 https://github.com/D-Programming-Language/d-programming-language.org
blob/master/simd.dd 



 and core.simd:

 https://github.com/D-Programming-Language/druntime/blob/master/src/core/simd.d 
Nice! Although... import core.simd; void main() { float4 a = void; // float a; doesn't work either a = simd(XMM.PXOR, a); }
Er... is there any reason why we're using such a cryptic PXOR value instead of operator overloading?
Jan 13 2012
parent reply Peter Alexander <peter.alexander.au gmail.com> writes:
On 13/01/12 8:02 PM, Mehrdad wrote:
 On 1/13/2012 11:06 AM, Peter Alexander wrote:
 On 13/01/12 8:39 AM, Walter Bright wrote:
 https://github.com/D-Programming-Language/d-programming-language.org/blob/master/simd.dd



 and core.simd:

 https://github.com/D-Programming-Language/druntime/blob/master/src/core/simd.d
Nice! Although... import core.simd; void main() { float4 a = void; // float a; doesn't work either a = simd(XMM.PXOR, a); }
Er... is there any reason why we're using such a cryptic PXOR value instead of operator overloading?
I imagine Walter will add the operator overloads later. The simd(op, ...) syntax is more flexible though because it allows you to select instructions that don't directly map to any standard operator (e.g. shuffles).
Jan 13 2012
parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 1/13/2012 12:27 PM, Peter Alexander wrote:
 On 13/01/12 8:02 PM, Mehrdad wrote:
 Er... is there any reason why we're using such a cryptic PXOR value
 instead of operator overloading?
I imagine Walter will add the operator overloads later.
Right. simd() is just the bottom layer building block. It's a compiler intrinsic, and I don't want to make every overload a compiler intrinsic.
 The simd(op, ...) syntax is more flexible though because it allows you to
select
 instructions that don't directly map to any standard operator (e.g. shuffles).
What's our vector, Victor? http://www.youtube.com/watch?v=fVq4_HhBK8Y
Jan 13 2012
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 1/13/12 2:41 PM, Walter Bright wrote:
 On 1/13/2012 12:27 PM, Peter Alexander wrote:
 On 13/01/12 8:02 PM, Mehrdad wrote:
 Er... is there any reason why we're using such a cryptic PXOR value
 instead of operator overloading?
I imagine Walter will add the operator overloads later.
Right. simd() is just the bottom layer building block. It's a compiler intrinsic, and I don't want to make every overload a compiler intrinsic.
People will want to pass a variable for op. Would that work? Andrei
Jan 13 2012
next sibling parent Manu <turkeyman gmail.com> writes:
On 14 January 2012 00:31, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org
 wrote:
 On 1/13/12 2:41 PM, Walter Bright wrote:

 On 1/13/2012 12:27 PM, Peter Alexander wrote:

 On 13/01/12 8:02 PM, Mehrdad wrote:

 Er... is there any reason why we're using such a cryptic PXOR value
 instead of operator overloading?
I imagine Walter will add the operator overloads later.
Right. simd() is just the bottom layer building block. It's a compiler intrinsic, and I don't want to make every overload a compiler intrinsic.
People will want to pass a variable for op. Would that work?
...I really don't think they will. and most people would never dive this deep if the standard lib does its job properly.
Jan 13 2012
prev sibling next sibling parent reply Peter Alexander <peter.alexander.au gmail.com> writes:
On 13/01/12 10:31 PM, Andrei Alexandrescu wrote:
 On 1/13/12 2:41 PM, Walter Bright wrote:
 On 1/13/2012 12:27 PM, Peter Alexander wrote:
 On 13/01/12 8:02 PM, Mehrdad wrote:
 Er... is there any reason why we're using such a cryptic PXOR value
 instead of operator overloading?
I imagine Walter will add the operator overloads later.
Right. simd() is just the bottom layer building block. It's a compiler intrinsic, and I don't want to make every overload a compiler intrinsic.
People will want to pass a variable for op. Would that work?
Why would people want to do that? Also, no, it can't possibly work. It just makes no sense.
Jan 13 2012
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 1/13/12 5:06 PM, Peter Alexander wrote:
 On 13/01/12 10:31 PM, Andrei Alexandrescu wrote:
 On 1/13/12 2:41 PM, Walter Bright wrote:
 On 1/13/2012 12:27 PM, Peter Alexander wrote:
 On 13/01/12 8:02 PM, Mehrdad wrote:
 Er... is there any reason why we're using such a cryptic PXOR value
 instead of operator overloading?
I imagine Walter will add the operator overloads later.
Right. simd() is just the bottom layer building block. It's a compiler intrinsic, and I don't want to make every overload a compiler intrinsic.
People will want to pass a variable for op. Would that work?
Why would people want to do that? Also, no, it can't possibly work. It just makes no sense.
My point exactly. The chosen syntax must be fixed. Andrei
Jan 13 2012
parent reply Mehrdad <wfunction hotmail.com> writes:
On 1/13/2012 3:51 PM, Andrei Alexandrescu wrote:
 On 1/13/12 5:06 PM, Peter Alexander wrote:
 On 13/01/12 10:31 PM, Andrei Alexandrescu wrote:
 On 1/13/12 2:41 PM, Walter Bright wrote:
 On 1/13/2012 12:27 PM, Peter Alexander wrote:
 On 13/01/12 8:02 PM, Mehrdad wrote:
 Er... is there any reason why we're using such a cryptic PXOR value
 instead of operator overloading?
I imagine Walter will add the operator overloads later.
Right. simd() is just the bottom layer building block. It's a compiler intrinsic, and I don't want to make every overload a compiler intrinsic.
People will want to pass a variable for op. Would that work?
Why would people want to do that? Also, no, it can't possibly work. It just makes no sense.
My point exactly. The chosen syntax must be fixed. Andrei
Still don't understand why we're not doing it with operator overloading instead...
Jan 13 2012
next sibling parent Walter Bright <newshound2 digitalmars.com> writes:
On 1/13/2012 11:30 PM, Mehrdad wrote:
 Still don't understand why we're not doing it with operator overloading
instead...
1. will not match the C ABI for vector types 2. will not generate correct vector symbolic debug info 3. will not match vector parameter name mangling 4. cannot do constant folding, or any optimizations which require semantic knowledge of the vector types 5. cannot optimize across inline asm blocks 6. cannot enregister the simd variables You'll be worse off than using the existing array vector syntax.
Jan 14 2012
prev sibling parent Peter Alexander <peter.alexander.au gmail.com> writes:
On 14/01/12 7:30 AM, Mehrdad wrote:
 On 1/13/2012 3:51 PM, Andrei Alexandrescu wrote:
 On 1/13/12 5:06 PM, Peter Alexander wrote:
 On 13/01/12 10:31 PM, Andrei Alexandrescu wrote:
 On 1/13/12 2:41 PM, Walter Bright wrote:
 On 1/13/2012 12:27 PM, Peter Alexander wrote:
 On 13/01/12 8:02 PM, Mehrdad wrote:
 Er... is there any reason why we're using such a cryptic PXOR value
 instead of operator overloading?
I imagine Walter will add the operator overloads later.
Right. simd() is just the bottom layer building block. It's a compiler intrinsic, and I don't want to make every overload a compiler intrinsic.
People will want to pass a variable for op. Would that work?
Why would people want to do that? Also, no, it can't possibly work. It just makes no sense.
My point exactly. The chosen syntax must be fixed. Andrei
Still don't understand why we're not doing it with operator overloading instead...
How do you do a vector shuffle with operator overloading?
Jan 14 2012
prev sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 1/13/2012 2:31 PM, Andrei Alexandrescu wrote:
 People will want to pass a variable for op. Would that work?
It'll currently fail miserably - it has to be a constant. Otherwise, we have runtime code generation. While not impossible, it is a large increase in scope.
Jan 13 2012
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 1/13/12 4:57 PM, Walter Bright wrote:
 On 1/13/2012 2:31 PM, Andrei Alexandrescu wrote:
 People will want to pass a variable for op. Would that work?
It'll currently fail miserably - it has to be a constant. Otherwise, we have runtime code generation. While not impossible, it is a large increase in scope.
Then probably the operation should be simd!opcode(arguments). If a function is intrinsic it shouldn't have special syntactic rights. Andrei
Jan 13 2012
parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 1/13/2012 3:51 PM, Andrei Alexandrescu wrote:
 On 1/13/12 4:57 PM, Walter Bright wrote:
 On 1/13/2012 2:31 PM, Andrei Alexandrescu wrote:
 People will want to pass a variable for op. Would that work?
It'll currently fail miserably - it has to be a constant. Otherwise, we have runtime code generation. While not impossible, it is a large increase in scope.
Then probably the operation should be simd!opcode(arguments). If a function is intrinsic it shouldn't have special syntactic rights.
You're right, I'm just not too thrilled about generating hundreds of template instantiations.
Jan 13 2012
next sibling parent Manu <turkeyman gmail.com> writes:
On 14 January 2012 03:42, Walter Bright <newshound2 digitalmars.com> wrote:

 On 1/13/2012 3:51 PM, Andrei Alexandrescu wrote:

 On 1/13/12 4:57 PM, Walter Bright wrote:

 On 1/13/2012 2:31 PM, Andrei Alexandrescu wrote:

 People will want to pass a variable for op. Would that work?
It'll currently fail miserably - it has to be a constant. Otherwise, we have runtime code generation. While not impossible, it is a large increase in scope.
Then probably the operation should be simd!opcode(arguments). If a function is intrinsic it shouldn't have special syntactic rights.
You're right, I'm just not too thrilled about generating hundreds of template instantiations.
Is that expensive somehow? Surely they all just boil down to a call to the intrinsic anyway?
Jan 13 2012
prev sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 1/13/12 7:42 PM, Walter Bright wrote:
 On 1/13/2012 3:51 PM, Andrei Alexandrescu wrote:
 On 1/13/12 4:57 PM, Walter Bright wrote:
 On 1/13/2012 2:31 PM, Andrei Alexandrescu wrote:
 People will want to pass a variable for op. Would that work?
It'll currently fail miserably - it has to be a constant. Otherwise, we have runtime code generation. While not impossible, it is a large increase in scope.
Then probably the operation should be simd!opcode(arguments). If a function is intrinsic it shouldn't have special syntactic rights.
You're right, I'm just not too thrilled about generating hundreds of template instantiations.
How is that possibly different from what you have now? Andrei
Jan 13 2012
parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 1/13/2012 7:03 PM, Andrei Alexandrescu wrote:
 How is that possibly different from what you have now?
Intrinsic functions are today just a table lookup in the compiler. Template intrinsics currently do not exist, so more code needs to be written for them.
Jan 13 2012
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 1/13/12 10:03 PM, Walter Bright wrote:
 On 1/13/2012 7:03 PM, Andrei Alexandrescu wrote:
 How is that possibly different from what you have now?
Intrinsic functions are today just a table lookup in the compiler.
They're a table lookup if the operation is a compile-time constant. So this argument does not apply.
 Template intrinsics currently do not exist, so more code needs to be
 written for them.
The same table lookup could be done, except in this case it would be more principled. Andrei
Jan 13 2012
parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 1/13/2012 8:52 PM, Andrei Alexandrescu wrote:
 On 1/13/12 10:03 PM, Walter Bright wrote:
 On 1/13/2012 7:03 PM, Andrei Alexandrescu wrote:
 How is that possibly different from what you have now?
Intrinsic functions are today just a table lookup in the compiler.
They're a table lookup if the operation is a compile-time constant. So this argument does not apply.
 Template intrinsics currently do not exist, so more code needs to be
 written for them.
The same table lookup could be done, except in this case it would be more principled.
You and I are talking about different things. The current compiler looks for intrinsics after all template functions are converted into real functions. The mangled name is looked up in a table to see if: 1. it is an intrinsic function 2. what is the corresponding expression node operator Doing it for intrinsic functions would require either: 1. adding hundreds of function signatures to the table 2. moving the intrinsic detection to the template instantiation logic
Jan 13 2012
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 1/13/12 11:02 PM, Walter Bright wrote:
 On 1/13/2012 8:52 PM, Andrei Alexandrescu wrote:
 On 1/13/12 10:03 PM, Walter Bright wrote:
 On 1/13/2012 7:03 PM, Andrei Alexandrescu wrote:
 How is that possibly different from what you have now?
Intrinsic functions are today just a table lookup in the compiler.
They're a table lookup if the operation is a compile-time constant. So this argument does not apply.
 Template intrinsics currently do not exist, so more code needs to be
 written for them.
The same table lookup could be done, except in this case it would be more principled.
You and I are talking about different things.
No. Please hear me out.
 The current compiler looks for intrinsics after all template functions
 are converted into real functions. The mangled name is looked up in a
 table to see if:

 1. it is an intrinsic function

 2. what is the corresponding expression node operator

 Doing it for intrinsic functions would require either:

 1. adding hundreds of function signatures to the table

 2. moving the intrinsic detection to the template instantiation logic
So this is an implementation issue that has nothing to do with doing the right thing. That's no reason to do the wrong thing. The real problem with the current approach is as follows. Defining an intrinsic function is cheating. It means the language's facilities are unable to expose computation to the compiler in a manner that makes it able to translate it to efficient code. This in turn points to problems in either the language or the compiler technology. To a good extent these are known issues of the state of the art. There are advantages to e.g. making integers intrinsic types and imbuing the compiler with understanding of basic arithmetic identities. Or it makes sense to define integral rotation as an intrinsic function (or devise a peephole optimization that detects the pattern) because it's one assembler operation deriving from a rather involved algorithm. So intrinsics are a necessary evil. On to your implementation of simd, which is simd(opcode, op1, op2) This is a lie - it's cheating twice. The expression looks like a function but does not feel like a function. The first argument, the opcode, is NOT a function parameter. It's part of the function. Passing a variable in there does not work as a matter of design - the generated code depends on that so opcode must be known during compilation. So what do we have to integrate the cheating operation within the current language semantics? I can think of two. First, make the operand part of the function name: simdOPCODE(op1, op2) This is reasonable because it acknowledges what really happens - each function has its identity and its generated code. The second, spaceship-era approach (and closer to the current implementation) is to make the first argument a template parameter. This is because template parameters must be known during compilation, which is exactly opcode's requirement: simd!opcode(op1, op2) Either approach should work perfectly fine; it "cheats in style" by using an existing language construct that exactly matches the special-cased capability. The current approach cheats badly - it messes with the language's fabric by defining a construct that's not a function but looks like one. I'd be in your debt if you could at least do the right thing when defining new intrinsics. Thanks, Andrei
Jan 16 2012
parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 1/16/2012 8:38 AM, Andrei Alexandrescu wrote:
 Either approach should work perfectly fine; it "cheats in style" by using an
 existing language construct that exactly matches the special-cased capability.
 The current approach cheats badly - it messes with the language's fabric by
 defining a construct that's not a function but looks like one.
You're right, it is cheating.
 I'd be in your debt if you could at least do the right thing when defining new
 intrinsics.
We can talk about that some more. At some point, there's going to have to be some compiler magic going on.
Jan 16 2012
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 1/16/12 1:32 PM, Walter Bright wrote:
 On 1/16/2012 8:38 AM, Andrei Alexandrescu wrote:
 Either approach should work perfectly fine; it "cheats in style" by
 using an
 existing language construct that exactly matches the special-cased
 capability.
 The current approach cheats badly - it messes with the language's
 fabric by
 defining a construct that's not a function but looks like one.
You're right, it is cheating.
 I'd be in your debt if you could at least do the right thing when
 defining new
 intrinsics.
We can talk about that some more. At some point, there's going to have to be some compiler magic going on.
OK. The overarching point is that the magic should be virtually indistinguishable from using the regular constructs. It's an optimization, and just like with any other optimization, you don't expect it to change the meaning of a construct. Andrei
Jan 16 2012
prev sibling next sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 1/13/2012 11:06 AM, Peter Alexander wrote:
 import core.simd;
 void main()
 {
 float4 a = void; // float a; doesn't work either
 a = simd(XMM.PXOR, a);
 }

 *** Internal error: backend/cgcod.c 2048 ***

 Are all those instructions implemented? I seem to get the same for all
 instructions.
The instructions are implemented, it's the initialization that isn't and is failing.
 Also, slight bikeshedding issue: I'm not so sure on using names like int4 for
 vectors. You see things like int32 a lot to mean a 32-bit integer, or int8 to
 mean an 8-bit integer. Using this notation for vectors may be confusing.

 As for what to change it to, I don't really care. int4v, vec_int4, int_vector4,
 anything. It doesn't matter.
If int4 is out, I'd prefer something like vint4. Something short.
Jan 13 2012
next sibling parent reply Peter Alexander <peter.alexander.au gmail.com> writes:
On 13/01/12 8:37 PM, Walter Bright wrote:
 On 1/13/2012 11:06 AM, Peter Alexander wrote:
 import core.simd;
 void main()
 {
 float4 a = void; // float a; doesn't work either
 a = simd(XMM.PXOR, a);
 }

 *** Internal error: backend/cgcod.c 2048 ***

 Are all those instructions implemented? I seem to get the same for all
 instructions.
The instructions are implemented, it's the initialization that isn't and is failing.
Oh ok. So is there any way to use them at the moment? None of these work: float4 a = void; float4 b; float4 c = [.0f, .0f, .0f, .0f]; float[4] v = [.0f, .0f, .0f, .0f]; float4 d = v;
Jan 13 2012
parent Walter Bright <newshound2 digitalmars.com> writes:
On 1/13/2012 12:59 PM, Peter Alexander wrote:
 So is there any way to use them at the moment?
Not unless you want to use inline asm to initialize them :-) I wouldn't bother, though, I hope to get initializing working shortly.
Jan 13 2012
prev sibling next sibling parent Manu <turkeyman gmail.com> writes:
On 13 January 2012 22:37, Walter Bright <newshound2 digitalmars.com> wrote:

 Also, slight bikeshedding issue: I'm not so sure on using names like int4
 for
 vectors. You see things like int32 a lot to mean a 32-bit integer, or
 int8 to
 mean an 8-bit integer. Using this notation for vectors may be confusing.

 As for what to change it to, I don't really care. int4v, vec_int4,
 int_vector4,
 anything. It doesn't matter.
If int4 is out, I'd prefer something like vint4. Something short.
It's a hard call. I like float4/int4, and like the similarity to Cg/HLSL personally. And these are the types that will be used 99% of the time. short8 is very rare by comparison... I'm quite apprehensive about making a compromise for the significantly less frequently used type. That said, it did make me a little uncomfortable the moment I read it...
Jan 13 2012
prev sibling next sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
Walter:

 What's our vector, Victor?
 http://www.youtube.com/watch?v=fVq4_HhBK8Y
Thank you Walter :-)
 If int4 is out, I'd prefer something like vint4. Something short.
Current names: void16 double2 float4 byte16 ubyte16 short8 ushort8 int4 uint4 long2 Your suggestion: vvoid16 vdouble2 vfloat4 vbyte16 vubyte16 vshort8 vushort8 vint4 vuint4 vlong2 My suggestion: void16v double2v float4v byte16v ubyte16v short8v ushort8v int4v uint4v long2v Bye, bearophile
Jan 13 2012
next sibling parent reply Manu <turkeyman gmail.com> writes:
On 13 January 2012 22:57, bearophile <bearophileHUGS lycos.com> wrote:

 Walter:

 What's our vector, Victor?
 http://www.youtube.com/watch?v=fVq4_HhBK8Y
Thank you Walter :-)
 If int4 is out, I'd prefer something like vint4. Something short.
Current names: void16 double2 float4 byte16 ubyte16 short8 ushort8 int4 uint4 long2 Your suggestion: vvoid16 vdouble2 vfloat4 vbyte16 vubyte16 vshort8 vushort8 vint4 vuint4 vlong2 My suggestion: void16v double2v float4v byte16v ubyte16v short8v ushort8v int4v uint4v long2v Bye, bearophile
I think I'd vote for leaving it as it is, swayed by the fact that the more ambiguous types are super-rarely used. float4/int4 has a nice familiarity with HLSL/Cg.
Jan 13 2012
next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 1/13/12 3:08 PM, Manu wrote:
 On 13 January 2012 22:57, bearophile <bearophileHUGS lycos.com
 <mailto:bearophileHUGS lycos.com>> wrote:

     Walter:

      > What's our vector, Victor?
      > http://www.youtube.com/watch?v=fVq4_HhBK8Y

     Thank you Walter :-)


      > If int4 is out, I'd prefer something like vint4. Something short.

     Current names:

     void16
     double2
     float4
     byte16
     ubyte16
     short8
     ushort8
     int4
     uint4
     long2

     Your suggestion:

     vvoid16
     vdouble2
     vfloat4
     vbyte16
     vubyte16
     vshort8
     vushort8
     vint4
     vuint4
     vlong2


     My suggestion:

     void16v
     double2v
     float4v
     byte16v
     ubyte16v
     short8v
     ushort8v
     int4v
     uint4v
     long2v

     Bye,
     bearophile


 I think I'd vote for leaving it as it is, swayed by the fact that the
 more ambiguous types are super-rarely used. float4/int4 has a nice
 familiarity with HLSL/Cg.
All names should have a __ prepended, and then the library defines names for them such as vec!(int, 4) that obey module lookup and all. Dumping a wheelbarrow of confusable new keywords doesn't sound right at all. Andrei
Jan 13 2012
next sibling parent Timon Gehr <timon.gehr gmx.ch> writes:
On 01/13/2012 11:36 PM, Andrei Alexandrescu wrote:
 On 1/13/12 3:08 PM, Manu wrote:
 On 13 January 2012 22:57, bearophile <bearophileHUGS lycos.com
 <mailto:bearophileHUGS lycos.com>> wrote:

 Walter:

 What's our vector, Victor?
 http://www.youtube.com/watch?v=fVq4_HhBK8Y
Thank you Walter :-)
 If int4 is out, I'd prefer something like vint4. Something short.
Current names: void16 double2 float4 byte16 ubyte16 short8 ushort8 int4 uint4 long2 Your suggestion: vvoid16 vdouble2 vfloat4 vbyte16 vubyte16 vshort8 vushort8 vint4 vuint4 vlong2 My suggestion: void16v double2v float4v byte16v ubyte16v short8v ushort8v int4v uint4v long2v Bye, bearophile I think I'd vote for leaving it as it is, swayed by the fact that the more ambiguous types are super-rarely used. float4/int4 has a nice familiarity with HLSL/Cg.
All names should have a __ prepended, and then the library defines names for them such as vec!(int, 4) that obey module lookup and all. Dumping a wheelbarrow of confusable new keywords doesn't sound right at all. Andrei
All of those are library types defined in core.simd. For example, float4 is declared as alias Vector!(float[4]) float4 And Vector simply hides what is built-in. template Vector(T){ alias __vector(T) Vector; } I think this is a very clean design.
Jan 13 2012
prev sibling next sibling parent Manu <turkeyman gmail.com> writes:
On 14 January 2012 00:36, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org
 wrote:
 On 1/13/12 3:08 PM, Manu wrote:

 On 13 January 2012 22:57, bearophile <bearophileHUGS lycos.com
 <mailto:bearophileHUGS lycos.**com <bearophileHUGS lycos.com>>> wrote:

    Walter:

     > What's our vector, Victor?
     > http://www.youtube.com/watch?**v=fVq4_HhBK8Y<http://www.youtube.com/watch?v=fVq4_HhBK8Y>

    Thank you Walter :-)


     > If int4 is out, I'd prefer something like vint4. Something short.

    Current names:

    void16
    double2
    float4
    byte16
    ubyte16
    short8
    ushort8
    int4
    uint4
    long2

    Your suggestion:

    vvoid16
    vdouble2
    vfloat4
    vbyte16
    vubyte16
    vshort8
    vushort8
    vint4
    vuint4
    vlong2


    My suggestion:

    void16v
    double2v
    float4v
    byte16v
    ubyte16v
    short8v
    ushort8v
    int4v
    uint4v
    long2v

    Bye,
    bearophile


 I think I'd vote for leaving it as it is, swayed by the fact that the
 more ambiguous types are super-rarely used. float4/int4 has a nice
 familiarity with HLSL/Cg.
All names should have a __ prepended, and then the library defines names for them such as vec!(int, 4) that obey module lookup and all. Dumping a wheelbarrow of confusable new keywords doesn't sound right at all.
These ARE the library defined types we're talking about, defined in simd.d
Jan 13 2012
prev sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 1/13/2012 2:36 PM, Andrei Alexandrescu wrote:
 All names should have a __ prepended, and then the library defines names for
 them such as vec!(int, 4) that obey module lookup and all. Dumping a
wheelbarrow
 of confusable new keywords doesn't sound right at all.
They're not keywords, they are (literally) simple aliases: alias Vector!(int[4]) int4; As aliases, they obey all scoping and disambiguation rules, which I think is superior to using __ prefixes. You could use Vector!(int[4]) everywhere instead, but I submit it's a bit klunky to do that and might as well provide a set of aliases (or else people will produce their own aliases and they'll all have different spellings).
Jan 13 2012
parent sclytrack <sclytrack fake.com> writes:
On 01/14/2012 12:00 AM, Walter Bright wrote:
 On 1/13/2012 2:36 PM, Andrei Alexandrescu wrote:
 All names should have a __ prepended, and then the library defines
 names for
 them such as vec!(int, 4) that obey module lookup and all. Dumping a
 wheelbarrow
 of confusable new keywords doesn't sound right at all.
They're not keywords, they are (literally) simple aliases: alias Vector!(int[4]) int4;
v4int
 As aliases, they obey all scoping and disambiguation rules, which I
 think is superior to using __ prefixes.

 You could use Vector!(int[4]) everywhere instead, but I submit it's a
 bit klunky to do that and might as well provide a set of aliases (or
 else people will produce their own aliases and they'll all have
 different spellings).
Jan 14 2012
prev sibling parent Shahid <govellius gmail.com> writes:
On Fri, 13 Jan 2012 23:08:42 +0200, Manu wrote:

 I think I'd vote for leaving it as it is, swayed by the fact that the
 more ambiguous types are super-rarely used. float4/int4 has a nice
 familiarity with HLSL/Cg.
I like the current name scheme, and would like to keep them too.
Jan 14 2012
prev sibling next sibling parent "Martin Nowak" <dawg dawgfoto.de> writes:
 void16v
 double2v
 float4v
 byte16v
 ubyte16v
 short8v
 ushort8v
 int4v
 uint4v
 long2v
+1
Jan 14 2012
prev sibling parent reply Sean Cavanaugh <WorksOnMyMachine gmail.com> writes:
What about the 256 bit types that are already present in AVX instruction 
set?

I've written a several C++ based SIMD math libraries (for SSE2 up 
through AVX), and PPC's VMX instruction sets that you can find on game 
consoles.

The variable type naming is probably the most annoying thing to work out.

For HLSL they use float, float1, float2, float3, float4 and int, uint 
and double versions, and this convention works out quite well until you 
start having to deal with smaller integer types or FP16 half floats.

However on the CPU side of things there are signed and unsigned 8, 16, 
32, 64 and 128 bit values.  It gets even more complicated in that not 
all the math operations or comparisons are supported on the non-32 bit 
types.  The hardware is really designed for you to pack and unpack the 
smaller types to 32 bit do the work and pack the results back, and the 
64 bit integer support is also a bit spotty (esp wrt multiply and divide).

On 1/13/2012 2:57 PM, bearophile wrote:
 Walter:

 What's our vector, Victor?
 http://www.youtube.com/watch?v=fVq4_HhBK8Y
Thank you Walter :-)
 If int4 is out, I'd prefer something like vint4. Something short.
Current names: void16 double2 float4 byte16 ubyte16 short8 ushort8 int4 uint4 long2 Your suggestion: vvoid16 vdouble2 vfloat4 vbyte16 vubyte16 vshort8 vushort8 vint4 vuint4 vlong2 My suggestion: void16v double2v float4v byte16v ubyte16v short8v ushort8v int4v uint4v long2v Bye, bearophile
Jan 14 2012
parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 1/14/2012 9:15 PM, Sean Cavanaugh wrote:
 What about the 256 bit types that are already present in AVX instruction set?
Eventually, I'd like to do them, too.
 I've written a several C++ based SIMD math libraries (for SSE2 up through AVX),
 and PPC's VMX instruction sets that you can find on game consoles.

 The variable type naming is probably the most annoying thing to work out.

 For HLSL they use float, float1, float2, float3, float4 and int, uint and
double
 versions, and this convention works out quite well until you start having to
 deal with smaller integer types or FP16 half floats.

 However on the CPU side of things there are signed and unsigned 8, 16, 32, 64
 and 128 bit values.
I'm not sure why the convention used in std.simd fails here.
 It gets even more complicated in that not all the math
 operations or comparisons are supported on the non-32 bit types.
Right. D is designed to give an error for operations that are not supported, rather than downgrade to emulation like gcc does.
Jan 14 2012
parent reply "Martin Nowak" <dawg dawgfoto.de> writes:
On Sun, 15 Jan 2012 06:21:22 +0100, Walter Bright  
<newshound2 digitalmars.com> wrote:

 On 1/14/2012 9:15 PM, Sean Cavanaugh wrote:
 What about the 256 bit types that are already present in AVX  
 instruction set?
Eventually, I'd like to do them, too.
I already did some work for adding AVX to the inline assembler. https://github.com/dawgfoto/dmd/commits/AVXSupport
Jan 14 2012
parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 1/14/2012 9:52 PM, Martin Nowak wrote:
 On Sun, 15 Jan 2012 06:21:22 +0100, Walter Bright <newshound2 digitalmars.com>
 wrote:

 On 1/14/2012 9:15 PM, Sean Cavanaugh wrote:
 What about the 256 bit types that are already present in AVX instruction set?
Eventually, I'd like to do them, too.
I already did some work for adding AVX to the inline assembler. https://github.com/dawgfoto/dmd/commits/AVXSupport
Nice, how about a pull request?
Jan 14 2012
parent "Martin Nowak" <dawg dawgfoto.de> writes:
On Sun, 15 Jan 2012 07:07:03 +0100, Walter Bright  
<newshound2 digitalmars.com> wrote:

 On 1/14/2012 9:52 PM, Martin Nowak wrote:
 On Sun, 15 Jan 2012 06:21:22 +0100, Walter Bright  
 <newshound2 digitalmars.com>
 wrote:

 On 1/14/2012 9:15 PM, Sean Cavanaugh wrote:
 What about the 256 bit types that are already present in AVX  
 instruction set?
Eventually, I'd like to do them, too.
I already did some work for adding AVX to the inline assembler. https://github.com/dawgfoto/dmd/commits/AVXSupport
Nice, how about a pull request?
It's still some instructions to go.
Jan 14 2012
prev sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 1/13/12 2:37 PM, Walter Bright wrote:
 If int4 is out, I'd prefer something like vint4. Something short.
Something short must compensate its potential for confusion with frequent usage and well-established convention. Arguably neither applies here. Andrei
Jan 13 2012
parent Timon Gehr <timon.gehr gmx.ch> writes:
On 01/13/2012 11:29 PM, Andrei Alexandrescu wrote:
 On 1/13/12 2:37 PM, Walter Bright wrote:
 If int4 is out, I'd prefer something like vint4. Something short.
Something short must compensate its potential for confusion with frequent usage and well-established convention. Arguably neither applies here. Andrei
Both apply. Frequent usage: Under the precondition that core.simd is imported, of course. Well-Established convention: See GLSL/HLSL/OpenCL/...
Jan 13 2012
prev sibling next sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 1/13/2012 11:06 AM, Peter Alexander wrote:
 Also, slight bikeshedding issue: I'm not so sure on using names like int4 for
 vectors. You see things like int32 a lot to mean a 32-bit integer, or int8 to
 mean an 8-bit integer. Using this notation for vectors may be confusing.
Consider also that the int8 is an alias, not a keyword. This means that the compiler will inform you of any ambiguities, as well as allow: core.simd.int8 to disambiguate.
Jan 13 2012
parent reply Peter Alexander <peter.alexander.au gmail.com> writes:
On 13/01/12 10:55 PM, Walter Bright wrote:
 On 1/13/2012 11:06 AM, Peter Alexander wrote:
 Also, slight bikeshedding issue: I'm not so sure on using names like
 int4 for
 vectors. You see things like int32 a lot to mean a 32-bit integer, or
 int8 to
 mean an 8-bit integer. Using this notation for vectors may be confusing.
Consider also that the int8 is an alias, not a keyword. This means that the compiler will inform you of any ambiguities, as well as allow: core.simd.int8 to disambiguate.
I realize that. It's just that I mentally associate the identifier int8 with an 8-bit integer as it is something I regularly see in C++ code. However, I'm willing to drop my position. After a quick Google, I discovered that it's not as common as I thought. I'm happy to keep float4 etc. since it is simple and is already used in a couple of shader languages.
Jan 13 2012
parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 1/13/2012 3:15 PM, Peter Alexander wrote:
 I realize that. It's just that I mentally associate the identifier int8 with an
 8-bit integer as it is something I regularly see in C++ code.

 However, I'm willing to drop my position. After a quick Google, I discovered
 that it's not as common as I thought. I'm happy to keep float4 etc. since it is
 simple and is already used in a couple of shader languages.
I know you agree with me but I'm not done arguing :-) Making an int8 type in D would be execrable style, as 'byte' is (unlike in C) *defined* to be an 8 bit signed integer.
Jan 13 2012
parent "F i L" <witte2008 gmail.com> writes:
Dope! Great starting place.

I think the syntax is great as-is. 'short' means a 16 bit integer 
type, so I don't see why short8 would conflict anywhere (in D). 
Plus, like Manu pointed out, float4/int4 is really what'll be 
most used and is identical to HLSL.

...to bad size_t wasn't intz like in Crack... ;-P
Jan 13 2012
prev sibling next sibling parent "Robert Jacques" <sandford jhu.edu> writes:
On Fri, 13 Jan 2012 13:06:28 -0600, Peter Alexander
<peter.alexander.au gmail.com> wrote:
 On 13/01/12 8:39 AM, Walter Bright wrote:
[snip]
 Also, slight bikeshedding issue: I'm not so sure on using names like
 int4 for vectors. You see things like int32 a lot to mean a 32-bit
 integer, or int8 to mean an 8-bit integer. Using this notation for
 vectors may be confusing.

 As for what to change it to, I don't really care. int4v, vec_int4,
 int_vector4, anything. It doesn't matter.
Well, in my experience (graphics/GPU), float4 is the standard nomenclature.
Jan 13 2012
prev sibling next sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 1/13/2012 11:06 AM, Peter Alexander wrote:
 *** Internal error: backend/cgcod.c 2048 ***

 Are all those instructions implemented? I seem to get the same for all
 instructions.
Things have gotten much better with the latest checkin.
Jan 14 2012
parent Peter Alexander <peter.alexander.au gmail.com> writes:
On 14/01/12 8:27 AM, Walter Bright wrote:
 On 1/13/2012 11:06 AM, Peter Alexander wrote:
 *** Internal error: backend/cgcod.c 2048 ***

 Are all those instructions implemented? I seem to get the same for all
 instructions.
Things have gotten much better with the latest checkin.
Ok, just got latest: float4 a = void; // this works now float4 b; // this doesn't (backend/cod2.c 2630) a = simd(XMM.PXOR, a, a); // this doesn't (backend/cgcod.c 2048) a = simd(XMM.PXOR, a, b); // this works a = simd(XMM.PXOR, b, a); // this works b = simd(XMM.PXOR, a, a); // this doesn't (backend/cgcod.c 2048) Seems to not like it when the two args are the same. This doesn't work either: asm { movaps a, b; } // (bad type/size of operands 'movaps') So, I can load all zeroes into a register using this: float4 a = void, b = void; b = a; a = simd(XMM.PXOR, a, b); But can't really do anything else. Also, is there any way to extract the information from a vector type? Using a union, or taking address and casting to float* didn't work. Presumably it isn't writing back into memory appropriately (or has no memory associated).
Jan 14 2012
prev sibling parent Jacob Carlborg <doob me.com> writes:
On 2012-01-13 20:06, Peter Alexander wrote:
 On 13/01/12 8:39 AM, Walter Bright wrote:
 https://github.com/D-Programming-Language/d-programming-language.org/blob/master/simd.dd



 and core.simd:

 https://github.com/D-Programming-Language/druntime/blob/master/src/core/simd.d
Nice! Although... import core.simd; void main() { float4 a = void; // float a; doesn't work either a = simd(XMM.PXOR, a); } *** Internal error: backend/cgcod.c 2048 *** Are all those instructions implemented? I seem to get the same for all instructions. Also, slight bikeshedding issue: I'm not so sure on using names like int4 for vectors. You see things like int32 a lot to mean a 32-bit integer, or int8 to mean an 8-bit integer. Using this notation for vectors may be confusing.
Doesn't some C libraries use these names for fixed size types?
 As for what to change it to, I don't really care. int4v, vec_int4,
 int_vector4, anything. It doesn't matter.
-- /Jacob Carlborg
Jan 14 2012
prev sibling parent deadalnix <deadalnix gmail.com> writes:
Le 13/01/2012 09:39, Walter Bright a écrit :
 https://github.com/D-Programming-Language/d-programming-language.org/blob/master/simd.dd


 and core.simd:

 https://github.com/D-Programming-Language/druntime/blob/master/src/core/simd.d
Let me propose something that solve this problem and many other. I never had time to explain it properly, but this is definitively interesting for this conversation, so I'll give a quick draft. The idea is to add a new ASM instruction to add an alias to a register choosen by the compiler and ensure it represent some existing variable. Thus, the compiler could ensure not to use a register already used and avoid stack manipulation when possible. This would also help ASM to get more readable. As register are not equal one to another, we need to specify which type of register we want to use. For that, we just replace the « variable » part of the register name by N. For exemple XMMN is any SSE register. RNX represent a general purpose register on x86_64. Now we define the false alias ASM instruction. Here is a (dumb) exemple : long toto = 42; long tata = 1337; asm { alias toto RNX; alias tata RNX; add toto tata; // Now toto is 1379. } If tot and tata are already in some register, the compiler can simply map. If they are in memory, the the compiler must choose a register and mov the right data into it.
Jan 14 2012