Kir*_*sky 11 c++ memory windows winapi visual-c++
是否有一个函数(SSEx内在函数可以),它将用指定的int32_t值填充内存?例如,当此值等于0xAABBCC00结果时,内存应如下所示:
AABBCC00AABBCC00AABBCC00AABBCC00AABBCC00
AABBCC00AABBCC00AABBCC00AABBCC00AABBCC00
AABBCC00AABBCC00AABBCC00AABBCC00AABBCC00
AABBCC00AABBCC00AABBCC00AABBCC00AABBCC00
...
Run Code Online (Sandbox Code Playgroud)
我可以使用std::fill或简单的for循环,但它不够快.
在程序开始时仅调整一次矢量的大小,这不是问题.瓶颈正在填补记忆.
简化代码:
struct X
{
typedef std::vector<int32_t> int_vec_t;
int_vec_t buffer;
X() : buffer( 5000000 ) { /* some more action */ }
~X() { /* some code here */ }
// the following function is called 25 times per second
const int_vec_t& process( int32_t background, const SOME_DATA& data );
};
const X::int_vec_t& X::process( int32_t background, const SOME_DATA& data )
{
// the following one string takes 30% of total time of #process function
std::fill( buffer.begin(), buffer.end(), background );
// some processing
// ...
return buffer;
}
Run Code Online (Sandbox Code Playgroud)
我就是这样做的(请原谅我的微软):
VOID FillInt32(__out PLONG M, __in LONG Fill, __in ULONG Count)
{
__m128i f;
// Fix mis-alignment.
if ((ULONG_PTR)M & 0xf)
{
switch ((ULONG_PTR)M & 0xf)
{
case 0x4: if (Count >= 1) { *M++ = Fill; Count--; }
case 0x8: if (Count >= 1) { *M++ = Fill; Count--; }
case 0xc: if (Count >= 1) { *M++ = Fill; Count--; }
}
}
f.m128i_i32[0] = Fill;
f.m128i_i32[1] = Fill;
f.m128i_i32[2] = Fill;
f.m128i_i32[3] = Fill;
while (Count >= 4)
{
_mm_store_si128((__m128i *)M, f);
M += 4;
Count -= 4;
}
// Fill remaining LONGs.
switch (Count & 0x3)
{
case 0x3: *M++ = Fill;
case 0x2: *M++ = Fill;
case 0x1: *M++ = Fill;
}
}
Run Code Online (Sandbox Code Playgroud)
我不得不问:你有没有明确地描述std::fill并证明它是性能瓶颈?我猜它是以一种非常有效的方式实现的,这样编译器就可以自动生成适当的指令(例如-march在gcc上).
如果它是瓶颈,它仍然可以从算法重新设计(如果可能的话)中获得更好的好处,以避免设置如此多的内存(显然是一遍又一遍),这样你再使用哪种填充机制并不重要.
感谢大家的回答。我已经检查了wj32 的解决方案,但它显示的时间与std::fill执行的非常相似。我当前的解决方案(在 Visual Studio 2008 中)的运行速度比std::fill借助该函数快 4 倍memcpy:
// fill the first quarter by the usual way
std::fill(buffer.begin(), buffer.begin() + buffer.size()/4, background);
// copy the first quarter to the second (very fast)
memcpy(&buffer[buffer.size()/4], &buffer[0], buffer.size()/4*sizeof(background));
// copy the first half to the second (very fast)
memcpy(&buffer[buffer.size()/2], &buffer[0], buffer.size()/2*sizeof(background));
Run Code Online (Sandbox Code Playgroud)
在生产代码中,需要添加检查是否buffer.size()能被 4 整除,并为此添加适当的处理。
| 归档时间: |
|
| 查看次数: |
6668 次 |
| 最近记录: |