相关文章推荐
胡子拉碴的椰子  ·  在 TypeScript ...·  10 月前    · 
儒雅的皮带  ·  C++ - Vector 计算 ...·  1 年前    · 
Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

I'm trying to write some SIMD code (in C++Builder 10.1 Berlin), but I'm getting an E2257 error in mmintrin.h (which is included by xmmintrin.h , which should be included for SIMD stuff). There's a bunch of identical errors, so it seems that bcc32 can't handle the syntax found in those headers.

For instance, all the lines containing __atribute__ seems to cause this error:

typedef long long __m64 __attribute__((__vector_size__(8)));

To me, this does seem like a C++builder bug, but I'm not sure, and to be honest I'm not familiar with __atribute__ (this doesn't seem to be a C++ keyword, so I assume it's either a function/macro or a language extension).

UPDATE: Since C++ Builder 10.1 Berlin can use Clang (bcc32c as opposed to the old compiler bcc32) , I tried that as well and that helped remove all the E2257 errors. Unfortunately, I'm now getting an ICE ( [bcc32c Error] FillObj.cpp(1): ICE: Internal compiler error: C0000005 @ 27287E3D ). The culprit is this line _mm_storeu_ps(&a[i], xmm0 ); Commenting out this line makes the code compile. This code is just an example but it's enough to recreate the problem.

#include <xmmintrin.h>
void SumValues(float * a, float * b, unsigned len){
    __m128 xmm0, xmm1;
    //for this simple example , it's assumed len is divisible by     
    for(int i=0; i<len; i += 4){
      xmm0 = _mm_loadu_ps( &a[i] );
      xmm1 = _mm_loadu_ps( &b[i] );
      xmm0 = _mm_add_ps(xmm0, xmm1);
      _mm_storeu_ps( &a[i], xmm0 );//this line is causing the ICE described above

As I said in a comment , this works fine in Qt (using MinGw 5.5.0 ). About the Clang compiler, I'm not exactly sure which version it is, but since it has to support all the VCL stuff, I don't think it's a standard clang compiler.

That syntax is a GNU C extension (gcc.gnu.org/onlinedocs/gcc/Vector-Extensions.html). Each compiler usually has its own version of headers like that, e.g. MSVC's would look nothing like that (instead using a union of structs). Are you manually using GCC's xmmintrin.h with bcc32? Are you sure bcc32 even supports SSE code-gen at all? community.idera.com/developer-tools/general-development/f/… does say there's a -mmmx command-line option which might also enable SSE. – Peter Cordes Jul 31, 2020 at 19:20 Where in the C++ Builder (Berlin version) documentation are you reading about __attribute__? – Eljay Jul 31, 2020 at 19:21 @Peter Cordes,I'm not sure that bcc32 supports SSE but these two headers come bundled with C++ builder so that was my assumption (this is not specific to C++ builder berlin, these headers have been a part of the c++ builder installation for as long as I remember). – dsp_user Jul 31, 2020 at 19:25 clang/LLVM will have no problem with GNU C extensions, including using the same syntax for vector extensions. If you can use a good modern compiler like clang, do it! Preferably with -march=pentium-m -mtune=haswell or something similar, if you want to assume SSE3 and other pretty old extensions as a baseline. – Peter Cordes Jul 31, 2020 at 19:41

I used the 10.4 Sydney 64-bit Windows C++ compiler in the IDE and your example compiles and executes for me.

void SumValues(float * a, float * b, unsigned len){
    __m128 xmm0, xmm1;
    //for this simple example , it's assumed len is divisible by
    for(int i=0; i<len; i += 4){
      xmm0 = _mm_loadu_ps( &a[i] );
      xmm1 = _mm_loadu_ps( &b[i] );
      xmm0 = _mm_add_ps(xmm0, xmm1);
      _mm_storeu_ps( &a[i], xmm0 );//this line is causing the ICE described above
__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
    float myA[4],myB[4];
    myA[0] = 0.0;
    myA[1] = 1.0;
    myA[2] = 2.0;
    myA[3] = 3.0;
    myB[0] = 0.0;
    myB[1] = 1.0;
    myB[2] = 2.0;
    myB[3] = 3.0;
    SumValues(myA,myB,4);
    Button1->Caption = FloatToStr(myA[2]);
                I found the following IFDEFs in the 10.4 source code:  #if defined(clang)    #if (clang_major == 5 && clang_minor == 0)      #include <clang5.0\xmmintrin.h>    #elif (clang_major == 3 && clang_minor == 3)      #include <clang3.3\xmmintrin.h>    #else      #error "Unable to determine correct clang header version"    #endif  #else      #error "Only supported for clang compilers"  #endif
– user186876
                Aug 9, 2020 at 15:26
                those ifdefs are not present in 10.1 Berlin (at least I didn't see them) so I can  assume they were    added in more recent versions of the compiler.
– dsp_user
                Aug 9, 2020 at 19:41
                I was also told by an Embarcadero employee (just yesterday via email)  that SSE stuff is supported only by 64-bit Clang compilers. The 32 bit compilers still pass values via FPU (he didn't specify reasons for this). This might explain why you managed to get my example working.
– dsp_user
                Aug 9, 2020 at 20:12
                in 10.4 Sydney the ifdef for clang with xmmintrin.h can be found in C:\Program Files (x86)\Embarcadero\Studio\21.0\include\windows\crtl\xmmintrin.h
– user186876
                Aug 9, 2020 at 21:35
        

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.