C SIMD:位于位和操作后存储UINT64_T值

C++ SIMD: Store uint64_t value after bitwise and operation

本文关键字:UINT64 存储 操作 SIMD 于位      更新时间:2023-10-16

我试图在两个uint64_t整数数组的元素之间进行位&,然后将结果存储在另一个数组中。这是我的程序:

#include <emmintrin.h>
#include <nmmintrin.h>
#include <chrono>

int main()
{
  uint64_t data[200];
  uint64_t data2[200];
  uint64_t data3[200];
  __m128i* ptr = (__m128i*) data;
  __m128i* ptr2 = (__m128i*) data2;
  uint64_t* ptr3 = data3;
  for (int i = 0; i < 100; ++i, ++ptr, ++ptr2, ptr3 += 2)
    _mm_store_ps(ptr3, _mm_and_si128(*ptr, *ptr2));
}

但是,我遇到了这个错误:

test.cpp:17:50: error: cannot convert ‘uint64_t* {aka long unsigned int*}’ to ‘float*’ for argument ‘1’ to ‘void _mm_store_ps(float*, __m128)’
     _mm_store_ps(ptr3, _mm_and_si128(*ptr, *ptr2));

由于某种原因,编译器认为我要复制到一系列浮子。是否可以使用uint64_t的阵列来做我要做的事情?

您可以使用_mm_store_si128

首先将指针ptr3更改为

  __m128i* ptr3 = (__m128i*) data3;

,然后

  for (int i = 0; i < 100; ++i, ++ptr, ++ptr2, ++ptr3)
    _mm_store_si128(ptr3, _mm_and_si128(*ptr, *ptr2));

您使用的是浮点操作_mm_store_ps,尽管您实际上想存储整数。因此,要么使用_mm_store_si128或将结果归还为uint64_t

您还应该确保将数组与16个字节相提并论,因此可以使用对齐的负载/存储操作,这将更快。

#include <emmintrin.h>
#include <nmmintrin.h>
#include <chrono>
int main()
{
  __declspec(align(16)) uint64_t data[200];
  __declspec(align(16)) uint64_t data2[200];
  __declspec(align(16)) uint64_t data3[200];
  __m128i* ptr = (__m128i*) data;
  __m128i* ptr2 = (__m128i*) data2;
  __m128i* ptr3 = (__m128i*) data3;
  for (int i = 0; i < 100; ++i, ++ptr, ++ptr2, ++ptr3)
    *ptr3 = _mm_and_si128(*ptr, *ptr2);
}