将16位短数组转换为32位int数组的有效方法?

Vla*_*mir 16 c c++ arrays copy

将无符号短数组(每个值16位)转换为无符号整数数组(每个值32位)的最有效方法是什么?

Kon*_*lph 14

复制它.

unsigned short source[]; // …
unsigned int target[]; // …
unsigned short* const end = source + sizeof source / sizeof source[0];
std::copy(source, end, target);
Run Code Online (Sandbox Code Playgroud)

std::copy内部选择给定输入类型的最佳复制机制.但是,在这种情况下,可能没有比在循环中单独复制元素更好的方法了.

  • 作为一个数据点,一个简单的循环和`std :: copy`都在我的Core2Duo上用GCC 4.5.2编译成相同的代码:一个循环使用`pmovsxwd`和`movdqu`处理任何reamaing元素.(用`-O3 -march = native -mtune = native`编译). (6认同)
  • @Dair这不会失败 - 它绝对有效.我测试过了. (2认同)

Naw*_*waz 9

std::copy在C++中使用:

#include<algorithm> //must include

unsigned short ushorts[M]; //where M is some const +ve integer
unsigned int   uints[N]; //where N >= M
//...fill ushorts
std::copy(ushorts, ushorts+M, uints);
Run Code Online (Sandbox Code Playgroud)

在C语言中,使用手动循环(实际上,您可以在C和C++中使用手动循环):

int i = 0;
while( i < M ) { uints[i] = ushorts[i]; ++i; }
Run Code Online (Sandbox Code Playgroud)


Pat*_*ter 6

这里是一个以64位块访问的展开循环.它可能比简单循环快一点,但测试是唯一可以知道的方法.

假设N是4的倍数,那个sizeof(short)是16位,并且使用64位寄存器.

 typedef union u {
     uint16_t    us[4];
     uint32_t    ui[2];
     uint64_t    ull;
 } u_t;
 ushort_t src[N] = ...;
 uint_t dst[N];

 u_t *p_src = (u_t *) src;
 u_t *p_dst = (u_t *) dst;
 uint_t i;
 u_t tmp, tmp2;
 for(i=0; i<N/4; i++) {
     tmp = p_src[i];    /* Read four shorts in one read access */
     tmp2.ui[0] = tmp.us[0];   /* The union trick avoids complicated shifts that are furthermore dependent on endianness. */
     tmp2.ui[1] = tmp.us[1];   /* The compiler should take care of optimal assembly decomposition. */ 
     p_dst[2*i] = tmp2;  /* Write the two first ints in one write access. */
     tmp2.ui[0] = tmp.us[2];
     tmp2.ui[1] = tmp.us[3];
     p_dst[2*i+1] = tmp2; /* Write the 2 next ints in 1 write access. */
 }
Run Code Online (Sandbox Code Playgroud)

编辑

所以我只是在具有GCC 3.4.1的SUN M5000(SPARC64 VII 2.5 GHz)上以64位模式在4,000,000个元件阵列上进行了测试.天真的实现速度要快一些.我尝试使用SUNStudio 12和GCC 4.3,但由于数组大小,我甚至无法编译程序.

EDIT2

我设法在GCC 4.3上编译它.优化版本比天真版本快一点.

              GCC 3.4          GCC 4.3
naive         11.1 ms          11.8 ms
optimized     12.4 ms          10.0 ms
Run Code Online (Sandbox Code Playgroud)

EDIT3

我们可以从中得出结论,就C而言,不要为复制循环的优化版本而烦恼,增益是如此之低,以至于错误的风险超过了收益.