Ошибка: выбор пользовательских типов данных в c

Это более простое представление о моей проблеме. Я хочу преобразовать значение float в определенный тип v4si (я хочу использовать SIMD-операцию для оптимизации.) Пожалуйста, помогите преобразовать значение float/double в определенный тип.

#include<stdio.h>

typedef double v4si __attribute__ ((vector_size (16)));

int main()
{
    double stoptime=36000;
    float x =0.5*stoptime;
    float * temp = &x;
    v4si a = ((v4si)x);   // Error: Incompatible data types
    v4si b;
    v4si *c;
    c = ((v4si*)&temp);   // Copies address of temp,           
    b = *(c);                   
    printf("%f\n" , b);      //    but printing (*c) crashes program
}

Ответ 1

Вам не нужно определять собственный тип вектора SIMD (v4si) или запутываться с помощью прикладов и пингом типа - просто используйте предоставленный intrinsics в соответствующем заголовке *intrin.h, например

#include <xmmintrin.h> // use SSE intrinsics 

int main(void)
{
    __m128 v;          // __m128 is the standard SSE vector type for 4 x float
    float x, y, z, w;

    v = _mm_set_ps(x, y, z, w);
                       // use intrinsic to set vector contents to x, y, z, w

    // ...

    return 0;
}

Ответ 2

Похоже, вы используете GCC vector extensions. Следующий код показывает, как делать трансляции, вектор + скаляр, вектор * скаляр, нагрузки и магазины с использованием векторных расширений.   #include

#if defined(__clang__)
typedef float v4sf __attribute__((ext_vector_type(4)));
#else
typedef float v4sf __attribute__ ((vector_size (16)));
#endif

void print_v4sf(v4sf a) { for(int i=0; i<4; i++) printf("%f ", a[i]); puts(""); }

int main(void) {
  v4sf a;
  //broadcast a scalar
  a = ((v4sf){} + 1)*3.14159f;  
  print_v4sf(a);

  // vector + scalar
  a += 3.14159f;
  print_v4sf(a);

  // vector*scalar
  a *= 3.14159f;
  print_v4sf(a);

  //load from array
  float data[] = {1, 2, 3, 4};
  a = *(v4sf*)data;
  //a = __builtin_ia32_loadups(data);

  //store to array
  float store[4];
  *(v4sf*)store = a;
  for(int i=0; i<4; i++) printf("%f ", store[i]); puts("");
}

Clang 4.0 и ICC 17 поддерживает подмножество расширений вектора GCC. Однако ни одна из них не поддерживает операции vector + scalar или vector*scalar, которые поддерживает GCC. Работа для Clang заключается в использовании расширений Vector Clang OpenCL. Я не знаю, как работать в ICC. MSVC не поддерживает любое расширение вектора, о котором я знаю.

С GCC, даже если он поддерживает vector + scalar и vector*scalar, вы не можете сделать vector = scalar (но вы можете использовать расширения Clang OpenCL). Вместо этого вы можете использовать этот трюк.

a = ((v4sf){} + 1)*3.14159f;

Я бы сделал, как предлагает Paul R, и использует встроенные функции, которые в основном совместимы с четырьмя основными компиляторами C/С++: GCC, Clang, ICC и MSVC.

Вот таблица того, что поддерживается каждым компилятором с использованием расширений вектора GCC и расширений вектора Clang OpenCL.

                                gcc  g++  clang  icc   OpenCL
unary operations                
[]                              yes  yes  yes    yes   yes
+, –                            yes  yes  yes    yes   yes
++, --                          yes  yes  yes    yes   yes 

binary vector op vector         
+,–,*,/,%                       yes  yes  yes    yes   yes    
&,|,^,~                         yes  yes  yes    yes   yes
>>,<<                           yes  yes  yes    yes   yes
==, !=, >, <, >=, <=            yes  yes  yes    yes   yes
!, &&, ||                       no   yes  no     no    yes

binary vector op scalar         
+,–,*,/,%                       yes  yes  no     no    yes
&,|,^,~                         yes  yes  no     no    yes
>>,<<                           yes  yes  no     no    yes
==, !=, >, <, >=, <=            yes  yes  no     no    yes                      
!, &&, ||                       no   yes  no     no    yes

assignment
vector = vector                 yes  yes  yes    yes   yes
vector = scalar                 no   no   no     no    yes                                              

ternary operator
?:                              no   yes  no     no    ?

Мы видим, что Clang и ICC не поддерживают операции GCC vector operator scalar. GCC в режиме С++ поддерживает все, кроме vector = scalar. Расширения Clang OpenCL поддерживают все, кроме трехмерного оператора. Документация Clang заявляет, что она работает, но я не могу заставить ее работать. Дополнительно GCC в режиме C не поддерживает двоичные логические операторы или тройной оператор.