在StackOverflow的其他地方,有人询问深度缓冲直方图 - 使用GLSL创建深度缓冲直方图纹理.
我正在编写一个iOS图像处理应用程序,并对此问题很感兴趣,但对提供的答案不清楚.那么,是否可以通过GLSL使用GPU创建图像直方图?
有没有人想过如何计算SSE4.x中8位整数向量的模式(统计量)?为了澄清,这将是128位寄存器中的16x8位值.
我希望结果作为矢量掩码选择模值元素.即结果_mm_cmpeq_epi8(v, set1(mode(v))),以及标量值.
提供一些额外的背景; 虽然上面的问题本身就是一个有趣的问题,但我已经通过线性复杂度可以想到的大多数算法.这个课程将消除我从计算这个数字中获得的任何收益.
我希望在这里与大家一起寻找一些深刻的魔法.这有可能是一个近似值可能需要打破这种结合,例如"选择一个频繁出现的元素"例如(NB差针对最),这将是值得的.概率答案也是可用的.
SSE和x86有一些非常有趣的语义.可能值得探索超优化传递.
我正在考虑如何在以下例程中加速位测试:
void histSubtractFromBits(uint64* cursor, uint16* hist){
//traverse each bit of the 256-bit-long bitstring by splitting up into 4 bitsets
std::bitset<64> a(*cursor);
std::bitset<64> b(*(cursor+1));
std::bitset<64> c(*(cursor+2));
std::bitset<64> d(*(cursor+3));
for(int bit = 0; bit < 64; bit++){
hist[bit] -= a.test(bit);
}
for(int bit = 0; bit < 64; bit++){
hist[bit+64] -= b.test(bit);
}
for(int bit = 0; bit < 64; bit++){
hist[bit+128] -= c.test(bit);
}
for(int bit = 0; bit < 64; bit++){
hist[bit+192] -= d.test(bit);
}
}
Run Code Online (Sandbox Code Playgroud)
实际的gcc实现对bit参数进行范围检查,然后使用位掩码对-s进行范围检查.我可以在没有位集和我自己的位移/屏蔽的情况下完成它,但我相当肯定不会产生任何显着的加速(告诉我,如果我错了,为什么).
我对x86-64程序集并不是很熟悉,但我知道有 …
首先,我有一个数组int a[1000][1000]。所有这些整数都在 0 到 32767 之间,它们是已知的常量:它们在程序运行期间永远不会改变。
其次,我有一个数组 b[32768],它包含 0 到 32 之间的整数。我使用这个数组将 a 中的所有数组映射到 32 个 bin:
int bins[32]{};
for (auto e : a[i])//mapping a[i] to 32 bins.
bins[b[e]]++;
Run Code Online (Sandbox Code Playgroud)
每次,数组 b 将用一个新数组初始化,我需要将数组 a 中的所有 1000 个数组(每个包含 1000 个整数)散列到 1000 个数组,每个数组包含 32 个整数,表示有多少整数落入其每个 bin 。
int new_array[32768] = {some new mapping};
copy(begin(new_array), end(new_array), begin(b));//reload array b;
int bins[1000][32]{};//output array to store results .
for (int i = 0; i < 1000;i++)
for (auto e : a[i])//hashing a[i] …Run Code Online (Sandbox Code Playgroud) 我想用 neon 内在函数优化直方图统计代码。但我没有成功。这是 c 代码:
#define NUM (7*1024*1024)
uint8 src_data[NUM];
uint32 histogram_result[256] = {0};
for (int i = 0; i < NUM; i++)
{
histogram_result[src_data[i]]++;
}
Run Code Online (Sandbox Code Playgroud)
Historam 统计更像是串行处理。用 neon 内在函数很难优化。有人知道如何优化吗?提前谢谢。
我想用AVX2指令加快以下操作,但我无法找到一种方法.
我得到了uint64_t data[100000]一大堆uint64_t和一个unsigned char indices[100000]字节数组.我想输出一个数组uint64_t Out[256],其中第i个值是所有data[j]这样的xor index[j]=i.
我想要的直接实现是这样的:
uint64_t Out[256] = {0}; // initialize output array
for (i = 0; i < 100000 ; i++) {
Out[Indices[i]] ^= data[i];
}
Run Code Online (Sandbox Code Playgroud)
我们可以使用AVX2指令更有效地实现这一点吗?
编辑:这是我的代码现在的样子
uint64_t Out[256][4] = {0}; // initialize output array
for (i = 0; i < 100000 ; i+=4) {
Out[Indices[i ]][0] ^= data[i];
Out[Indices[i+1]][1] ^= data[i+1];
Out[Indices[i+2]][2] ^= data[i+2];
Out[Indices[i+3]][3] ^= data[i+3];
}
Run Code Online (Sandbox Code Playgroud) 我的完整代码中有一段代码:
\nconst unsigned int GL=8000000;\nconst int cuba=8;\nconst int cubn=cuba+cuba;\nconst int cub3=cubn*cubn*cubn;\nint Length[cub3];\nint Begin[cub3];\nint Counter[cub3];\nint MIndex[GL];\nstruct Particle{\n int ix,jy,kz;\n int ip;\n};\nParticle particles[GL];\nint GetIndex(const Particle & p){return (p.ix+cuba+cubn*(p.jy+cuba+cubn*(p.kz+cuba)));} \n...\n#pragma omp parallel for\nfor(int i=0; i<cub3; ++i) Length[i]=Counter[i]=0;\n#pragma omp parallel for\nfor(int i=0; i<N; ++i)\n{\n int ic=GetIndex(particles[i]);\n #pragma omp atomic update\n Length[ic]++;\n}\nBegin[0]=0;\n#pragma omp single\nfor(int i=1; i<cub3; ++i) Begin[i]=Begin[i-1]+Length[i-1];\n#pragma omp parallel for\nfor(int i=0; i<N; ++i)\n{\n if(particles[i].ip==3)\n {\n int ic=GetIndex(particles[i]);\n if(ic>cub3 || ic<0) printf("ic=%d out of range!\\n",ic);\n int cnt=0;\n #pragma omp atomic capture\n cnt=Counter[ic]++;\n MIndex[Begin[ic]+cnt]=i;\n }\n}\n …Run Code Online (Sandbox Code Playgroud) 我有一个特别的问题。我将尝试尽可能准确地描述这一点。
我正在做一个非常重要的“微优化”。一次运行数天的循环。所以如果我能减少这个循环时间,它需要一半的时间。10 天将减少到只有 5 天等。
我现在拥有的循环是函数:“testbenchmark1”。
我有 4 个索引需要在这样的循环中增加。但是当从列表中访问索引时,实际上需要一些额外的时间,正如我所注意到的。这就是我想知道是否有其他解决方案。
indexes[n]++; //increase correct index
“testbenchmark1”的完整代码需要 122 毫秒:
void testbenchmark00()
{
Random random = new Random();
List<int> indexers = new List<int>();
for (int i = 0; i < 9256408; i++)
{
indexers.Add(random.Next(0, 4));
}
int[] valueLIST = indexers.ToArray();
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
int[] indexes = { 0, 0, 0, 0 };
foreach (int n in valueLIST) //Takes 122 ms
{
indexes[n]++; //increase correct index
}
stopWatch.Stop();
MessageBox.Show("stopWatch: " + stopWatch.ElapsedMilliseconds.ToString() …Run Code Online (Sandbox Code Playgroud)