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在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)
这里是一个以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而言,不要为复制循环的优化版本而烦恼,增益是如此之低,以至于错误的风险超过了收益.
| 归档时间: |
|
| 查看次数: |
4366 次 |
| 最近记录: |