Community

Following the discussion on D's hashtables, and my current understanding that D doesn't implement any of the x86 CPU features beyond Pentium Pro (same as C and most other things for that matter) I took another quick peek at D's predefined Versions.
Currently, when I want to use asm {} I have to use:
version(D_InlineAsm_X86)
Unfortunately, this doesn't cover anything to do with most of the later instruction extensions D claims to support in the spec, such as the SSE, SSE2, SSE3, SSSE3, MMX, 3DNow! instruction sets, let alone x86_64. Ultimately, one would want to have a cascading support mechanism, such that if I want to use SSSE3, I'm obviating that the processor must support everything before it:
version(D_InlineAsm_x86)
version(D_InlineAsm_x86_3DNow)
version(D_InlineAsm_x86_MMX)
version(D_InlineAsm_x86_SSE)
version(D_InlineAsm_x86_SSE2)
version(D_InlineAsm_x86_SSE3)
version(D_InlineAsm_x86_SSSE3)
version(D_InlineAsm_x86_SSE4)
version(D_InlineAsm_x86_64)
Predefining those so that compiler writers can raise errors if they don't yet support SSE3 instructions, but they do support x86 and MMX, would be a smart thing to do. It would also allow implementors to write code that WON'T compile and try to run if the user's CPU doesn't support it - preventing what could be a devastating crash.
Sincerely,
Dan

Dan wrote:
> Following the discussion on D's hashtables, and my current understanding that D doesn't implement any of the x86 CPU features beyond Pentium Pro (same as C and most other things for that matter) I took another quick peek at D's predefined Versions.
>
> Currently, when I want to use asm {} I have to use:
>
> version(D_InlineAsm_X86)
>
> Unfortunately, this doesn't cover anything to do with most of the later instruction extensions D claims to support in the spec, such as the SSE, SSE2, SSE3, SSSE3, MMX, 3DNow! instruction sets, let alone x86_64. Ultimately, one would want to have a cascading support mechanism, such that if I want to use SSSE3, I'm obviating that the processor must support everything before it:
>
> version(D_InlineAsm_x86)
> version(D_InlineAsm_x86_3DNow)
> version(D_InlineAsm_x86_MMX)
> version(D_InlineAsm_x86_SSE)
> version(D_InlineAsm_x86_SSE2)
> version(D_InlineAsm_x86_SSE3)
> version(D_InlineAsm_x86_SSSE3)
> version(D_InlineAsm_x86_SSE4)
> version(D_InlineAsm_x86_64)
>
> Predefining those so that compiler writers can raise errors if they don't yet support SSE3 instructions, but they do support x86 and MMX, would be a smart thing to do. It would also allow implementors to write code that WON'T compile and try to run if the user's CPU doesn't support it - preventing what could be a devastating crash.
The inline assembler does support all the SSE3 instructions, etc.

Walter Bright Wrote:
> > Predefining those so that compiler writers can raise errors if they don't yet support SSE3 instructions, but they do support x86 and MMX, would be a smart thing to do. It would also allow implementors to write code that WON'T compile and try to run if the user's CPU doesn't support it - preventing what could be a devastating crash.
>
> The inline assembler does support all the SSE3 instructions, etc.
Yes, the GDC and DMD implementations support all the SSE3 instructions, but someone with a i486 Pentium Pro does not, and neither might another D implementation implementing the D language spec.
When I use an SSE3 instruction in D, is it going to raise an error if the person's system is only a Pentium Pro?
If that could be done by checking the CPU support for each instruction implicitly, then it would be even better than versioning it all off... but I don't think that's the case - and it's not specified?

Dan wrote:
<snip>
> Yes, the GDC and DMD implementations support all the SSE3 instructions, but someone with a i486 Pentium Pro does not, and neither might another D implementation implementing the D language spec.
>
> When I use an SSE3 instruction in D, is it going to raise an error if the person's system is only a Pentium Pro?
>
> If that could be done by checking the CPU support for each instruction implicitly, then it would be even better than versioning it all off... but I don't think that's the case - and it's not specified?
>
Wouldn't you need runtime checking for cpu capabilities most of the time
anyway? The functions in std.cpuid should get you a long way in most
cases. Only works for x86, though.

"Dan" <murpsoft@hotmail.com> wrote in message
news:eurruh$26gc$1@digitalmars.com...
> Walter Bright Wrote:
>
> Yes, the GDC and DMD implementations support all the SSE3 instructions,
> but someone with a i486 Pentium Pro does not, and neither might another D
> implementation implementing the D language spec.
>
> When I use an SSE3 instruction in D, is it going to raise an error if the
> person's system is only a Pentium Pro?
>
> If that could be done by checking the CPU support for each instruction
> implicitly, then it would be even better than versioning it all off...
> but I don't think that's the case - and it's not specified?
>
Just because their machine doesn't support it, why wouldn't you allow
someone to use SSE3 instructions? For that matter, who says you have to be
running the compiler on an x86 platform to compile to x86 machine code?

Dan wrote:
> Walter Bright Wrote:
>>> Predefining those so that compiler writers can raise errors if they don't yet support SSE3 instructions, but they do support x86 and MMX, would be a smart thing to do. It would also allow implementors to write code that WON'T compile and try to run if the user's CPU doesn't support it - preventing what could be a devastating crash.
>> The inline assembler does support all the SSE3 instructions, etc.
>
> Yes, the GDC and DMD implementations support all the SSE3 instructions, but someone with a i486 Pentium Pro does not, and neither might another D implementation implementing the D language spec.
>
> When I use an SSE3 instruction in D, is it going to raise an error if the person's system is only a Pentium Pro?
>
> If that could be done by checking the CPU support for each instruction implicitly, then it would be even better than versioning it all off... but I don't think that's the case - and it's not specified?
I think what you need is a runtime check, which is provided in std.cpuid.

Dan wrote:
> Following the discussion on D's hashtables, and my current understanding that D doesn't implement any of the x86 CPU features beyond Pentium Pro (same as C and most other things for that matter) I took another quick peek at D's predefined Versions.
>
> Currently, when I want to use asm {} I have to use:
>
> version(D_InlineAsm_X86)
>
> Unfortunately, this doesn't cover anything to do with most of the later instruction extensions D claims to support in the spec, such as the SSE, SSE2, SSE3, SSSE3, MMX, 3DNow! instruction sets, let alone x86_64. Ultimately, one would want to have a cascading support mechanism, such that if I want to use SSSE3, I'm obviating that the processor must support everything before it:
>
> version(D_InlineAsm_x86)
> version(D_InlineAsm_x86_3DNow)
> version(D_InlineAsm_x86_MMX)
> version(D_InlineAsm_x86_SSE)
> version(D_InlineAsm_x86_SSE2)
> version(D_InlineAsm_x86_SSE3)
> version(D_InlineAsm_x86_SSSE3)
> version(D_InlineAsm_x86_SSE4)
> version(D_InlineAsm_x86_64)
>
> Predefining those so that compiler writers can raise errors if they don't yet support SSE3 instructions, but they do support x86 and MMX, would be a smart thing to do. It would also allow implementors to write code that WON'T compile and try to run if the user's CPU doesn't support it - preventing what could be a devastating crash.
>
> Sincerely,
> Dan
What would be nice is if you could tell the compiler to spit out DLLs
for each version (for your release build) and also a tiny exe that would
run the right one.
-Joel

Walter Bright Wrote:
> I think what you need is a runtime check, which is provided in std.cpuid.
So what you're saying is, we can't optimize the compiler for a specific variation of the x86, and are therefore stuck with writing generic programs that branch off for each cpu kind during runtime?
@Jarrett: It would be completely pointless to virtualize SSE3, or any other x86 upgrade. They provide instructions to assist with optimization. Virtualizing it is a huge de-optimization.
If you somehow version'd off some asm, you could write asm for x86_64, one for x86 with SSE2, and one for the rest, and you'd have reasonable version control with fallbacks. If the compiler was targetting an x86 without any extensions, it would automatically choose the right code.
Is it bad to allow that?

On Tue, 03 Apr 2007 10:48:01 -0400, Dan wrote:
> Walter Bright Wrote:
>> I think what you need is a runtime check, which is provided in std.cpuid.
>
> So what you're saying is, we can't optimize the compiler for a specific
> variation of the x86, and are therefore stuck with writing generic
> programs that branch off for each cpu kind during runtime?
No, maybe you missed the point. It certainly is possible for one to create
editions of an application for specific hardware configurations; and using
the version() statement is a reasonable way to do that.
version(SSE2) { . . . }
version(SSE) { . . . }
etc...
dmd -version=SSE2 myapp.d
dmd -version=SSE myapp.d
However, such editions should be able to be generated regardless of which
hardware architecure the compiler just happens to be running on at the
time. In other words, setting the version values within the compiler based
on the hardware at compilation time is not very useful. It would be better
to set these version values at the compiler command line level, if one does
really want hardware-specific editions of the app.
--
Derek Parnell
Melbourne, Australia
"Justice for David Hicks!"
skype: derek.j.parnell

Dan wrote:
> Walter Bright Wrote:
>> I think what you need is a runtime check, which is provided in std.cpuid.
>
> So what you're saying is, we can't optimize the compiler for a specific variation of the x86, and are therefore stuck with writing generic programs that branch off for each cpu kind during runtime?
Dan,
I think that there are two seperate issues. The D_InlineAsm_X86 seems to
mean "this compiler supports inline asm" rather than "this compiler is
targetting X86". I think it's reasonable to require that any compiler
which supports X86 inline asm should support *all* X86 opcodes.
However...
I think we do need to work out a way of specifying the CPU target -- but
that should be accessible even if inline asm is not supported. (For
example, you may want to call a library function which uses SSE3, even
if you're not using it yourself).
Yes, it's possible to detect the CPU type at runtime, but the
performance penalty is appalling for very short functions. I think the
ideal would be a install-time linker -- link in the appropriate code
during installation! The CPU type will always be the same, every time
it's run. But version names would be a great first step.
Standard names for the CPU targets needs to happen. Otherwise everyone
will make up their own.