相关疑难解决方法(0)

如何计算32位整数中的设置位数?

代表数字7的8位看起来像这样:

00000111
Run Code Online (Sandbox Code Playgroud)

设置三位.

什么算法来确定32位整数中的设置位数?

algorithm binary bit-manipulation hammingweight iec10967

838
推荐指数
31
解决办法
52万
查看次数

为memcpy增强了REP MOVSB

我想使用增强的REP MOVSB(ERMSB)为自定义获得高带宽memcpy.

ERMSB引入了Ivy Bridge微体系结构.如果您不知道ERMSB是什么,请参阅英特尔优化手册中的"增强型REP MOVSB和STOSB操作(ERMSB)" 部分.

我知道直接执行此操作的唯一方法是使用内联汇编.我从https://groups.google.com/forum/#!topic/gnu.gcc.help/-Bmlm_EG_fE获得了以下功能

static inline void *__movsb(void *d, const void *s, size_t n) {
  asm volatile ("rep movsb"
                : "=D" (d),
                  "=S" (s),
                  "=c" (n)
                : "0" (d),
                  "1" (s),
                  "2" (n)
                : "memory");
  return d;
}
Run Code Online (Sandbox Code Playgroud)

然而,当我使用它时,带宽远小于memcpy. 使用我的i7-6700HQ(Skylake)系统,Ubuntu 16.10,DDR4 @ 2400 MHz双通道32 GB,GCC 6.2,__movsb获得15 GB/s并memcpy获得26 GB/s.

为什么带宽如此低REP MOVSB?我该怎么做才能改善它?

这是我用来测试它的代码.

//gcc -O3 -march=native -fopenmp foo.c
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include …
Run Code Online (Sandbox Code Playgroud)

c x86 assembly gcc memcpy

56
推荐指数
4
解决办法
1万
查看次数

在x86上做水平浮点矢量和的最快方法

你有一个三(或四)个浮点数的向量.总结它们的最快方法是什么?

SSE(movaps,shuffle,add,movd)总是比x87快吗?SSE4.2中的水平加法说明值得吗?移动到FPU的成本是多少,然后是faddp,faddp?什么是最快的特定指令序列?

"尝试安排事情,这样你可以一次总结四个向量"将不被接受作为答案.:-)

floating-point optimization x86 assembly sse

41
推荐指数
4
解决办法
2万
查看次数

位数:预处理器魔术与现代C++

假设我想为16位块中的64位整数创建一个编译时构造的位计数查找表.我知道这样做的唯一方法是以下代码:

#define B4(n) n, n + 1, n + 1, n + 2
#define B6(n)   B4(n),   B4(n + 1),   B4(n + 1),  B4(n + 2)  
#define B8(n)   B6(n),   B6(n + 1),   B6(n + 1),  B6(n + 2)
#define B10(n)  B8(n),   B8(n + 1),   B8(n + 1),  B8(n + 2)
#define B12(n)  B10(n),  B10(n + 1),  B10(n + 1), B10(n + 2)
#define B14(n)  B12(n),  B12(n + 1),  B12(n + 1), B12(n + 2)
#define B16(n)  B14(n),  B14(n + 1),  B14(n …
Run Code Online (Sandbox Code Playgroud)

c++ bit-manipulation c-preprocessor c++11 c++14

38
推荐指数
3
解决办法
6083
查看次数

在某个位置或更低位置计算设置位的有效方法是什么?

给定std::bitset<64> bits任意数量的位和位位置X(0-63)

在X位或更低位计数位的最有效方法是什么,如果未设置X位,则返回0

注意:如果设置该位,则返回始终至少为1

蛮力方式很慢:

int countupto(std::bitset<64> bits, int X)
{
  if (!bits[X]) return 0;
  int total=1;
  for (int i=0; i < X; ++i)
  {
    total+=bits[i];
  }
  return total;
}
Run Code Online (Sandbox Code Playgroud)

这个count()方法bitset将为您popcount提供所有位,但bitset不支持范围

注意:这不是如何计算32位整数中的设置位数?因为它询问所有位而不是0到X的范围

c++ algorithm performance bit-manipulation

33
推荐指数
4
解决办法
5006
查看次数

为什么通过浮点矩阵乘法执行浮点比使用int int更快?

有两个int矩阵A和B,超过1000行和10K列,我经常需要将它们转换为float矩阵以获得加速(4x或更多).

我想知道为什么会这样?我意识到有许多优化和矢量化,如AVX等,继续浮点矩阵乘法.但是,对于整数(如果我没有记错的话),有指令如AVX2.并且,不能使用SSE和AVX作为整数?

为什么在矩阵代数库(如Numpy或Eigen)下面没有启发式来捕获它并像浮点一样更快地执行整数矩阵乘法?

关于已接受的答案:虽然@ sascha的答案非常有用且相关,@ chatz的答案是int乘以int的实际原因,无论是否存在BLAS整数矩阵运算.

c++ numpy matrix eigen

25
推荐指数
2
解决办法
1814
查看次数

向量<bool>上的按位运算

什么是执行按位操作的最佳方法vector<bool>

据我所知,vector<bool>是一个每布尔使用一位的特化.我选择vector<bool>了节省内存的原因.我知道存在一些问题vector<bool>但是对于我的需要它是合适的.

现在 - 对整个这样的向量进行逐位运算的最高效方法是什么?

如果我在for循环中读取并读出每个bool并将其存储回来,我理解它的方式是在内部执行更多操作以访问实际值.

谢谢!

c++ bitwise-operators bitvector

17
推荐指数
1
解决办法
1万
查看次数

使用英特尔上的SSE2减少无溢出的无符号字节数

我试图在Intel i3处理器上找到32个元素(每个1字节数据)的总和减少量.我这样做了:

s=0; 
for (i=0; i<32; i++)
{
    s = s + a[i];
}  
Run Code Online (Sandbox Code Playgroud)

但是,由于我的应用程序是一个需要更少时间的实时应用程序,因此需要花费更多时间.请注意,最终金额可能超过255.

有没有办法可以使用低级SIMD SSE2指令实现这一点?不幸的是我从未使用过SSE.我试图为此目的搜索sse2函数,但它也不可用.(sse)是否可以保证减少这种小型问题的计算时间?

有什么建议??

注意:我已经使用OpenCL和CUDA实现了类似的算法,虽然问题规模很大,但效果很好.对于小型问题,开销成本更高.不确定它在SSE上是如何工作的

x86 sse simd sse2 sse3

13
推荐指数
2
解决办法
4952
查看次数

你会如何转置二进制矩阵?

我在C++中有二进制矩阵,我用8位值向量重复.

例如,以下矩阵:

1 0 1 0 1 0 1
0 1 1 0 0 1 1
0 0 0 1 1 1 1
Run Code Online (Sandbox Code Playgroud)

表示为:

const uint8_t matrix[] = {
    0b01010101,
    0b00110011,
    0b00001111,
};
Run Code Online (Sandbox Code Playgroud)

我这样做的原因是因为然后计算这样的矩阵和8位向量的乘积变得非常简单和有效(每行只有一个按位AND和奇偶校验计算),这比单独计算每个位.

我现在正在寻找一种有效的方法来转置这样的矩阵,但是我无法弄清楚如何在不必手动计算每个位的情况下进行转换.

只是为了澄清一下,对于上面的例子,我想从转置中得到以下结果:

const uint8_t transposed[] = {
    0b00000000,
    0b00000100,
    0b00000010,
    0b00000110,
    0b00000001,
    0b00000101,
    0b00000011,
    0b00000111,
};
Run Code Online (Sandbox Code Playgroud)

注意:我更喜欢一种算法,它可以用任意大小的矩阵来计算,但我也对只能处理某些大小的算法感兴趣.

c++ math binary transpose matrix

10
推荐指数
3
解决办法
2780
查看次数

C中的二元向量和矩阵操作

我试图在C中实现一个数据结构,这将允许我有效地操作**二进制**矩阵(仅包含1或0).我将解释我必须对此矩阵应用哪些操作,并想知道使用哪种最佳数据结构?

操作在字段F_2中完成(这意味着1 + 1 = 0,其他操作保持不变).我有一个k*n矩阵(k< n)调用H.最多k= 2325和n= 3009.

我必须对此矩阵执行的操作是:

我将仅使用行交换和行添加来部分对角化它.一旦完成,我将不再使用行操作,并将在此矩阵上运行大量(!)列添加(我的意思是"很多"是关于((nk)/ 2)³列添加)

我正在考虑矩阵的数据结构:

对于矩阵系数,我考虑在一个单个unsigned int中一次存储多个位的序列.例如,我可以将序列存储(11001011)uint8_t 203(从二进制转换为十进制)

  • 这是个好主意吗 ?

如果我这样做,我有两个选择:

我可以使用uint16_tuint64_t系数在许多4*4或8*8子矩阵中分割我的矩阵H.

  • 这是一个很好的选择(在时间效率方面),如果是,是否更好地使用uint16_tuint64_t

另外我想存储每一行中的多个uint32_tuint64_t,然后操作我的部分对角化.接下来切换到将矩阵编码为n列向量以处理剩余操作的结构.

  • 你认为这更有效吗?

无论我使用什么方法,我都必须有效地访问nunsigned int(uint16,3264)的第一位.我怎么做 ?

c binary matrix time-complexity space-complexity

5
推荐指数
1
解决办法
1797
查看次数

如何在此循环中获得始终如一的高吞吐量?

在优化内循环的过程中,我遇到了奇怪的性能行为,我无法理解和纠正.

代码的精简版本如下; 粗略地说,有一个巨大的数组被分成16个字块,我简单地将每个块中字的前导零的数量加起来.(实际上我正在使用Dan Luupopcnt代码,但是在这里我选择了一个具有类似性能特征的简单指令,用于"简洁".Dan Luu的代码基于这个SO问题的答案,虽然它具有诱人的类似奇怪的结果,似乎没有在这里回答我的问题.)

// -*- compile-command: "gcc -O3 -march=native -Wall -Wextra -std=c99 -o clz-timing clz-timing.c" -*-
#include <stdint.h>
#include <time.h>
#include <stdlib.h>
#include <stdio.h>

#define ARRAY_LEN 16

// Return the sum of the leading zeros of each element of the ARRAY_LEN
// words starting at u.
static inline uint64_t clz_array(const uint64_t u[ARRAY_LEN]) {
    uint64_t c0 = 0;
    for (int i = 0; i < ARRAY_LEN; ++i) {
        uint64_t t0;
        __asm__ ("lzcnt %1, …
Run Code Online (Sandbox Code Playgroud)

c c++ performance assembly caching

4
推荐指数
1
解决办法
139
查看次数