digitalmars.D - start on SIMD documentation
- Walter Bright (3/3) Jan 13 2012 https://github.com/D-Programming-Language/d-programming-language.org/blo...
- Peter Alexander (18/21) Jan 13 2012 Nice!
- Peter Alexander (9/36) Jan 13 2012 Sorry, the code was meant to be:
- bearophile (4/11) Jan 13 2012 It's not confusing for D programmers. But if you want to be on the safe ...
- Iain Buclaw (11/39) Jan 13 2012 b/master/simd.dd
- Walter Bright (3/6) Jan 13 2012 ??
- Iain Buclaw (10/50) Jan 13 2012 ob/master/simd.dd
- Manu (10/14) Jan 13 2012 I had the same feeling.
- Peter Alexander (12/27) Jan 13 2012 Honestly, I be happy with any name as long as it was unambiguous.
- Mehrdad (3/21) Jan 13 2012 Er... is there any reason why we're using such a cryptic PXOR value
- Peter Alexander (5/29) Jan 13 2012 I imagine Walter will add the operator overloads later.
- Walter Bright (5/11) Jan 13 2012 Right. simd() is just the bottom layer building block. It's a compiler
- Andrei Alexandrescu (3/11) Jan 13 2012 People will want to pass a variable for op. Would that work?
- Manu (4/21) Jan 13 2012 ...I really don't think they will.
- Peter Alexander (3/14) Jan 13 2012 Why would people want to do that?
- Andrei Alexandrescu (3/18) Jan 13 2012 My point exactly. The chosen syntax must be fixed.
- Mehrdad (3/25) Jan 13 2012 Still don't understand why we're not doing it with operator overloading
- Walter Bright (9/10) Jan 14 2012 1. will not match the C ABI for vector types
- Peter Alexander (2/29) Jan 14 2012 How do you do a vector shuffle with operator overloading?
- Walter Bright (3/4) Jan 13 2012 It'll currently fail miserably - it has to be a constant. Otherwise, we ...
- Andrei Alexandrescu (4/9) Jan 13 2012 Then probably the operation should be simd!opcode(arguments). If a
- Walter Bright (3/12) Jan 13 2012 You're right, I'm just not too thrilled about generating hundreds of tem...
- Manu (3/22) Jan 13 2012 Is that expensive somehow?
- Andrei Alexandrescu (3/17) Jan 13 2012 How is that possibly different from what you have now?
- Walter Bright (3/4) Jan 13 2012 Intrinsic functions are today just a table lookup in the compiler. Templ...
- Andrei Alexandrescu (6/11) Jan 13 2012 They're a table lookup if the operation is a compile-time constant. So
- Walter Bright (9/20) Jan 13 2012 You and I are talking about different things.
- Andrei Alexandrescu (43/68) Jan 16 2012 So this is an implementation issue that has nothing to do with doing the...
- Walter Bright (4/10) Jan 16 2012 We can talk about that some more. At some point, there's going to have t...
- Andrei Alexandrescu (6/20) Jan 16 2012 OK. The overarching point is that the magic should be virtually
- Walter Bright (3/17) Jan 13 2012 If int4 is out, I'd prefer something like vint4. Something short.
- Peter Alexander (8/22) Jan 13 2012 Oh ok.
- Walter Bright (3/4) Jan 13 2012 Not unless you want to use inline asm to initialize them :-)
- Manu (6/17) Jan 13 2012 It's a hard call. I like float4/int4, and like the similarity to Cg/HLSL
- bearophile (37/40) Jan 13 2012 Current names:
- Manu (4/44) Jan 13 2012 I think I'd vote for leaving it as it is, swayed by the fact that the mo...
- Andrei Alexandrescu (5/50) Jan 13 2012 All names should have a __ prepended, and then the library defines names...
- Timon Gehr (9/74) Jan 13 2012 All of those are library types defined in core.simd.
- Manu (2/68) Jan 13 2012 These ARE the library defined types we're talking about, defined in simd...
- Walter Bright (8/11) Jan 13 2012 They're not keywords, they are (literally) simple aliases:
- sclytrack (2/16) Jan 14 2012
- Shahid (2/5) Jan 14 2012 I like the current name scheme, and would like to keep them too.
- Martin Nowak (1/11) Jan 14 2012 +1
- Sean Cavanaugh (16/56) Jan 14 2012 What about the 256 bit types that are already present in AVX instruction...
- Walter Bright (5/16) Jan 14 2012 I'm not sure why the convention used in std.simd fails here.
- Martin Nowak (4/8) Jan 14 2012 I already did some work for adding AVX to the inline assembler.
- Walter Bright (2/11) Jan 14 2012 Nice, how about a pull request?
- Martin Nowak (3/17) Jan 14 2012 It's still some instructions to go.
- Andrei Alexandrescu (5/6) Jan 13 2012 Something short must compensate its potential for confusion with
- Timon Gehr (5/11) Jan 13 2012 Both apply.
- Walter Bright (5/8) Jan 13 2012 Consider also that the int8 is an alias, not a keyword. This means that ...
- Peter Alexander (7/17) Jan 13 2012 I realize that. It's just that I mentally associate the identifier int8
- Walter Bright (4/9) Jan 13 2012 I know you agree with me but I'm not done arguing :-)
- F i L (6/6) Jan 13 2012 Dope! Great starting place.
- Robert Jacques (3/10) Jan 13 2012 Well, in my experience (graphics/GPU), float4 is the standard nomenclatu...
- Walter Bright (2/5) Jan 14 2012 Things have gotten much better with the latest checkin.
- Peter Alexander (20/26) Jan 14 2012 Ok, just got latest:
- Jacob Carlborg (4/31) Jan 14 2012 --
- deadalnix (24/27) Jan 14 2012 Let me propose something that solve this problem and many other. I never...
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
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.dNice! 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
On 13/01/12 7:06 PM, Peter Alexander wrote:On 13/01/12 8:39 AM, Walter Bright wrote: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.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.dNice! 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
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
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:b/master/simd.ddhttps://github.com/D-Programming-Language/d-programming-language.org/blo=simd.dand core.simd: https://github.com/D-Programming-Language/druntime/blob/master/src/core/=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';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.
Jan 13 2012
On 1/13/2012 11:18 AM, Iain Buclaw wrote:This is probably intelligable, but makes sense to me. Change int4 -> v4siplease, no!Vector names that reflect the MODE they represent, rather than the TYPE.??
Jan 13 2012
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:ob/master/simd.ddOn 13/01/12 8:39 AM, Walter Bright wrote:https://github.com/D-Programming-Language/d-programming-language.org/bl=/simd.dand core.simd: https://github.com/D-Programming-Language/druntime/blob/master/src/core=4Nice! 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=rfor vectors. You see things like int32 a lot to mean a 32-bit integer, o=Unintelligible, even... --=20 Iain Buclaw *(p < e ? p++ : p) =3D (c & 0x0f) + '0';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.
Jan 13 2012
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
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
On 1/13/2012 11:06 AM, Peter Alexander wrote:On 13/01/12 8:39 AM, Walter Bright wrote:Er... is there any reason why we're using such a cryptic PXOR value instead of operator overloading?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.dNice! Although... import core.simd; void main() { float4 a = void; // float a; doesn't work either a = simd(XMM.PXOR, a); }
Jan 13 2012
On 13/01/12 8:02 PM, Mehrdad wrote:On 1/13/2012 11:06 AM, Peter Alexander wrote: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).On 13/01/12 8:39 AM, Walter Bright wrote:Er... is there any reason why we're using such a cryptic PXOR value instead of operator overloading?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.dNice! Although... import core.simd; void main() { float4 a = void; // float a; doesn't work either a = simd(XMM.PXOR, a); }
Jan 13 2012
On 1/13/2012 12:27 PM, Peter Alexander wrote:On 13/01/12 8:02 PM, Mehrdad wrote: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.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).What's our vector, Victor? http://www.youtube.com/watch?v=fVq4_HhBK8Y
Jan 13 2012
On 1/13/12 2:41 PM, Walter Bright wrote:On 1/13/2012 12:27 PM, Peter Alexander wrote:People will want to pass a variable for op. Would that work? AndreiOn 13/01/12 8:02 PM, Mehrdad wrote: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.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.
Jan 13 2012
On 14 January 2012 00:31, Andrei Alexandrescu <SeeWebsiteForEmail erdani.orgwrote:On 1/13/12 2:41 PM, Walter Bright wrote:...I really don't think they will. and most people would never dive this deep if the standard lib does its job properly.On 1/13/2012 12:27 PM, Peter Alexander wrote:People will want to pass a variable for op. Would that work?On 13/01/12 8:02 PM, Mehrdad wrote: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.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.
Jan 13 2012
On 13/01/12 10:31 PM, Andrei Alexandrescu wrote:On 1/13/12 2:41 PM, Walter Bright wrote:Why would people want to do that? Also, no, it can't possibly work. It just makes no sense.On 1/13/2012 12:27 PM, Peter Alexander wrote:People will want to pass a variable for op. Would that work?On 13/01/12 8:02 PM, Mehrdad wrote: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.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.
Jan 13 2012
On 1/13/12 5:06 PM, Peter Alexander wrote:On 13/01/12 10:31 PM, Andrei Alexandrescu wrote:My point exactly. The chosen syntax must be fixed. AndreiOn 1/13/12 2:41 PM, Walter Bright wrote:Why would people want to do that? Also, no, it can't possibly work. It just makes no sense.On 1/13/2012 12:27 PM, Peter Alexander wrote:People will want to pass a variable for op. Would that work?On 13/01/12 8:02 PM, Mehrdad wrote: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.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.
Jan 13 2012
On 1/13/2012 3:51 PM, Andrei Alexandrescu wrote:On 1/13/12 5:06 PM, Peter Alexander wrote:Still don't understand why we're not doing it with operator overloading instead...On 13/01/12 10:31 PM, Andrei Alexandrescu wrote:My point exactly. The chosen syntax must be fixed. AndreiOn 1/13/12 2:41 PM, Walter Bright wrote:Why would people want to do that? Also, no, it can't possibly work. It just makes no sense.On 1/13/2012 12:27 PM, Peter Alexander wrote:People will want to pass a variable for op. Would that work?On 13/01/12 8:02 PM, Mehrdad wrote: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.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.
Jan 13 2012
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
On 14/01/12 7:30 AM, Mehrdad wrote:On 1/13/2012 3:51 PM, Andrei Alexandrescu wrote:How do you do a vector shuffle with operator overloading?On 1/13/12 5:06 PM, Peter Alexander wrote:Still don't understand why we're not doing it with operator overloading instead...On 13/01/12 10:31 PM, Andrei Alexandrescu wrote:My point exactly. The chosen syntax must be fixed. AndreiOn 1/13/12 2:41 PM, Walter Bright wrote:Why would people want to do that? Also, no, it can't possibly work. It just makes no sense.On 1/13/2012 12:27 PM, Peter Alexander wrote:People will want to pass a variable for op. Would that work?On 13/01/12 8:02 PM, Mehrdad wrote: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.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.
Jan 14 2012
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
On 1/13/12 4:57 PM, Walter Bright wrote:On 1/13/2012 2:31 PM, Andrei Alexandrescu wrote:Then probably the operation should be simd!opcode(arguments). If a function is intrinsic it shouldn't have special syntactic rights. AndreiPeople 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
On 1/13/2012 3:51 PM, Andrei Alexandrescu wrote:On 1/13/12 4:57 PM, Walter Bright wrote:You're right, I'm just not too thrilled about generating hundreds of template instantiations.On 1/13/2012 2:31 PM, Andrei Alexandrescu wrote:Then probably the operation should be simd!opcode(arguments). If a function is intrinsic it shouldn't have special syntactic rights.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
On 14 January 2012 03:42, Walter Bright <newshound2 digitalmars.com> wrote:On 1/13/2012 3:51 PM, Andrei Alexandrescu wrote:Is that expensive somehow? Surely they all just boil down to a call to the intrinsic anyway?On 1/13/12 4:57 PM, Walter Bright wrote:You're right, I'm just not too thrilled about generating hundreds of template instantiations.On 1/13/2012 2:31 PM, Andrei Alexandrescu wrote:Then probably the operation should be simd!opcode(arguments). If a function is intrinsic it shouldn't have special syntactic rights.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
On 1/13/12 7:42 PM, Walter Bright wrote:On 1/13/2012 3:51 PM, Andrei Alexandrescu wrote:How is that possibly different from what you have now? AndreiOn 1/13/12 4:57 PM, Walter Bright wrote:You're right, I'm just not too thrilled about generating hundreds of template instantiations.On 1/13/2012 2:31 PM, Andrei Alexandrescu wrote:Then probably the operation should be simd!opcode(arguments). If a function is intrinsic it shouldn't have special syntactic rights.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
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
On 1/13/12 10:03 PM, Walter Bright wrote:On 1/13/2012 7:03 PM, Andrei Alexandrescu wrote:They're a table lookup if the operation is a compile-time constant. So this argument does not apply.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.The same table lookup could be done, except in this case it would be more principled. Andrei
Jan 13 2012
On 1/13/2012 8:52 PM, Andrei Alexandrescu wrote:On 1/13/12 10:03 PM, Walter Bright wrote: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 logicOn 1/13/2012 7:03 PM, Andrei Alexandrescu wrote:They're a table lookup if the operation is a compile-time constant. So this argument does not apply.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.The same table lookup could be done, except in this case it would be more principled.
Jan 13 2012
On 1/13/12 11:02 PM, Walter Bright wrote:On 1/13/2012 8:52 PM, Andrei Alexandrescu wrote:No. Please hear me out.On 1/13/12 10:03 PM, Walter Bright wrote:You and I are talking about different things.On 1/13/2012 7:03 PM, Andrei Alexandrescu wrote:They're a table lookup if the operation is a compile-time constant. So this argument does not apply.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.The same table lookup could be done, except in this case it would be more principled.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 logicSo 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
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
On 1/16/12 1:32 PM, Walter Bright wrote:On 1/16/2012 8:38 AM, Andrei Alexandrescu wrote: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. AndreiEither 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
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
On 13/01/12 8:37 PM, Walter Bright wrote:On 1/13/2012 11:06 AM, Peter Alexander wrote: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;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.
Jan 13 2012
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
On 13 January 2012 22:37, Walter Bright <newshound2 digitalmars.com> wrote: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...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
Walter:What's our vector, Victor? http://www.youtube.com/watch?v=fVq4_HhBK8YThank 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
On 13 January 2012 22:57, bearophile <bearophileHUGS lycos.com> wrote:Walter: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.What's our vector, Victor? http://www.youtube.com/watch?v=fVq4_HhBK8YThank 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
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
On 01/13/2012 11:36 PM, Andrei Alexandrescu wrote:On 1/13/12 3:08 PM, Manu wrote: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.On 13 January 2012 22:57, bearophile <bearophileHUGS lycos.com <mailto:bearophileHUGS lycos.com>> wrote: Walter: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. AndreiWhat's our vector, Victor? http://www.youtube.com/watch?v=fVq4_HhBK8YThank 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
On 14 January 2012 00:36, Andrei Alexandrescu <SeeWebsiteForEmail erdani.orgwrote:On 1/13/12 3:08 PM, Manu wrote:These ARE the library defined types we're talking about, defined in simd.dOn 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.
Jan 13 2012
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
On 01/14/2012 12:00 AM, Walter Bright wrote:On 1/13/2012 2:36 PM, Andrei Alexandrescu wrote:v4intAll 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 14 2012
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
void16v double2v float4v byte16v ubyte16v short8v ushort8v int4v uint4v long2v+1
Jan 14 2012
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_HhBK8YThank 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
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
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:I already did some work for adding AVX to the inline assembler. https://github.com/dawgfoto/dmd/commits/AVXSupportWhat about the 256 bit types that are already present in AVX instruction set?Eventually, I'd like to do them, too.
Jan 14 2012
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:Nice, how about a pull request?On 1/14/2012 9:15 PM, Sean Cavanaugh wrote:I already did some work for adding AVX to the inline assembler. https://github.com/dawgfoto/dmd/commits/AVXSupportWhat about the 256 bit types that are already present in AVX instruction set?Eventually, I'd like to do them, too.
Jan 14 2012
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:It's still some instructions to go.On Sun, 15 Jan 2012 06:21:22 +0100, Walter Bright <newshound2 digitalmars.com> wrote:Nice, how about a pull request?On 1/14/2012 9:15 PM, Sean Cavanaugh wrote:I already did some work for adding AVX to the inline assembler. https://github.com/dawgfoto/dmd/commits/AVXSupportWhat about the 256 bit types that are already present in AVX instruction set?Eventually, I'd like to do them, too.
Jan 14 2012
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
On 01/13/2012 11:29 PM, Andrei Alexandrescu wrote:On 1/13/12 2:37 PM, Walter Bright wrote:Both apply. Frequent usage: Under the precondition that core.simd is imported, of course. Well-Established convention: See GLSL/HLSL/OpenCL/...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
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
On 13/01/12 10:55 PM, Walter Bright wrote:On 1/13/2012 11:06 AM, 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.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
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
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
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
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
On 14/01/12 8:27 AM, Walter Bright wrote:On 1/13/2012 11:06 AM, Peter Alexander wrote: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).*** 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
On 2012-01-13 20:06, Peter Alexander wrote:On 13/01/12 8:39 AM, Walter Bright wrote:Doesn't some C libraries use these names for fixed size types?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.dNice! 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.-- /Jacob Carlborg
Jan 14 2012
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.dLet 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