我一直认为这std::vector是"作为阵列实施的一般智慧",等等等等等等.今天我去了测试它,似乎不是这样:
这是一些测试结果:
UseArray completed in 2.619 seconds
UseVector completed in 9.284 seconds
UseVectorPushBack completed in 14.669 seconds
The whole thing completed in 26.591 seconds
Run Code Online (Sandbox Code Playgroud)
这大约慢了3-4倍!没有真正证明" vector可能会慢几纳米"的评论.
我使用的代码:
#include <cstdlib>
#include <vector>
#include <iostream>
#include <string>
#include <boost/date_time/posix_time/ptime.hpp>
#include <boost/date_time/microsec_time_clock.hpp>
class TestTimer
{
public:
TestTimer(const std::string & name) : name(name),
start(boost::date_time::microsec_clock<boost::posix_time::ptime>::local_time())
{
}
~TestTimer()
{
using namespace std;
using namespace boost;
posix_time::ptime now(date_time::microsec_clock<posix_time::ptime>::local_time());
posix_time::time_duration d = now - start;
cout << name << " completed in " << …Run Code Online (Sandbox Code Playgroud) 我正在寻找一种有效的方法来确定在整数中设置的最低有效位的位置,例如对于0x0FF0,它将是4.
这是一个简单的实现:
unsigned GetLowestBitPos(unsigned value)
{
assert(value != 0); // handled separately
unsigned pos = 0;
while (!(value & 1))
{
value >>= 1;
++pos;
}
return pos;
}
Run Code Online (Sandbox Code Playgroud)
任何想法如何挤出一些周期?
(注意:这个问题适合喜欢这类事情的人,而不是人们告诉我xyzoptimization是邪恶的.)
[编辑] 感谢大家的想法!我也学到了其他一些东西.凉!
我的问题很简单:std :: vector元素是否保证是连续的?在order word中,我可以使用指向std :: vector的第一个元素的指针作为C数组吗?
如果我的记忆力很好,那么C++标准就没有这样的保证.但是,如果元素不连续,那么std :: vector要求几乎不可能满足它们.
有人可以澄清一下吗?
例:
std::vector<int> values;
// ... fill up values
if( !values.empty() )
{
int *array = &values[0];
for( int i = 0; i < values.size(); ++i )
{
int v = array[i];
// do something with 'v'
}
}
Run Code Online (Sandbox Code Playgroud) 使用向量,可以假设元素连续存储在内存中,允许范围[&vec [0],&vec [vec.capacity())用作普通数组.例如,
vector<char> buf;
buf.reserve(N);
int M = read(fd, &buf[0], N);
Run Code Online (Sandbox Code Playgroud)
但现在向量不知道它包含M个字节的数据,由read()外部添加.我知道vector :: resize()设置了大小,但它也清除了数据,因此在read()调用之后它不能用于更新大小.
是否有一种简单的方法可以将数据直接读入矢量并在之后更新大小?是的,我知道明显的解决方法,比如使用一个小数组作为临时读缓冲区,并使用vector :: insert()将它附加到向量的末尾:
char tmp[N];
int M = read(fd, tmp, N);
buf.insert(buf.end(), tmp, tmp + M)
Run Code Online (Sandbox Code Playgroud)
这是有效的(这就是我今天正在做的事情),但是如果我可以将数据直接放入向量中,那么在那里会有一个额外的复制操作,这是困扰我的.
那么,在外部添加数据时,是否有一种简单的方法来修改矢量大小?
如果你有一个输入数组和一个输出数组,但是你只想写那些通过某个条件的元素,那么在AVX2中这样做最有效的方法是什么?
我在SSE看到它是这样做的:(来自:https://deplinenoise.files.wordpress.com/2015/03/gdc2015_afredriksson_simd.pdf)
__m128i LeftPack_SSSE3(__m128 mask, __m128 val)
{
// Move 4 sign bits of mask to 4-bit integer value.
int mask = _mm_movemask_ps(mask);
// Select shuffle control data
__m128i shuf_ctrl = _mm_load_si128(&shufmasks[mask]);
// Permute to move valid values to front of SIMD register
__m128i packed = _mm_shuffle_epi8(_mm_castps_si128(val), shuf_ctrl);
return packed;
}
Run Code Online (Sandbox Code Playgroud)
这对于4宽的SSE来说似乎很好,因此只需要16个入口LUT,但对于8宽的AVX,LUT变得非常大(256个条目,每个32个字节或8k).
我很惊讶AVX似乎没有简化此过程的指令,例如带有打包的蒙版存储.
我想通过稍微改变来计算左边设置的符号位数,你可以生成必要的排列表,然后调用_mm256_permutevar8x32_ps.但这也是我认为的一些指示......
有没有人知道用AVX2做这个的任何技巧?或者什么是最有效的方法?
以下是上述文件中左包装问题的说明:
谢谢