小编dsh*_*hin的帖子

微优化c ++比较功能

我有一个Compare()看起来像这样的函数:

inline bool Compare(bool greater, int p1, int p2) {
  if (greater) return p1>=p2;
  else return p1<=p2;
}
Run Code Online (Sandbox Code Playgroud)

我决定优化以避免分支:

inline bool Compare2(bool greater, int p1, int p2) {
  bool ret[2] = {p1<=p2,p1>=p2};
  return ret[greater];
}
Run Code Online (Sandbox Code Playgroud)

然后,我通过这样做测试:

bool x = true;
int M = 100000;
int N = 100;

bool a[N];
int b[N];
int c[N];

for (int i=0;i<N; ++i) {
  a[i] = rand()%2;
  b[i] = rand()%128;
  c[i] = rand()%128;
}

// Timed the below loop with both Compare() and …
Run Code Online (Sandbox Code Playgroud)

c++ optimization branch-prediction

12
推荐指数
1
解决办法
1516
查看次数

Multiset统治算法

让我们说如果N中的每个元素在M中至少出现多次,则多个集合M 支配另一个多集N.

给定一个目标多集M和一个整数k> 0,我想找到一个列表,L,大小-K多集,其总和占主导地位M.我想这个名单是小的成本,我的成本函数是形式:

cost = c*m + n

其中c是常量,m是L中多重集的数量,n是L中不同多重集的数量.

我怎样才能做到这一点?找到最优解的有效算法将是理想的.

问题来自于尝试使用专门的块打印机来执行客户打印页面的订单,该打印机一次打印k页.设置块打印机以打印k页的特定模板是昂贵的,但是一旦初始化模板,使用它进行打印是便宜的.目标多集M表示客户的订单,列表L的n个不同的多集表示n个不同的k页模板.

在我的特定应用中,M通常具有> 30个元素,其多重性在[10 ^ 4,10 ^ 6]的范围内.k的值为15,c约为10 ^ -5.

algorithm multiset

7
推荐指数
0
解决办法
241
查看次数

慢速XOR运算符

编辑:的确,我的计时代码中出现了一个奇怪的错误,导致了这些结果.当我修复错误时,智能版本按预期更快地结束.我的时间码看起来像这样:

bool x = false;
before = now();
for (int i=0; i<N; ++i) {
  x ^= smart_xor(A[i],B[i]);
}
after = now();
Run Code Online (Sandbox Code Playgroud)

我这样做是^=为了阻止我的编译器优化for循环.但我认为它以^=某种方式奇怪地与两个xor函数交互.我改变了我的定时代码,只需填写xor结果数组,然后在定时代码之外用该数组进行计算.那个固定的东西.

我应该删除这个问题吗?

结束编辑

我定义了两个C++函数如下:

bool smart_xor(bool a, bool b) {
  return a^b;
}

bool dumb_xor(bool a, bool b) {
  return a?!b:b;
}
Run Code Online (Sandbox Code Playgroud)

我的时序测试表明它dumb_xor()稍快一些(内联时为1.31ns vs 1.90ns,未内联时为1.92ns vs 2.21ns).这让我很困惑,因为^操作员应该是一台机器操作.我想知道是否有人有解释.

程序集看起来像这样(当没有内联时):

    .file   "xor.cpp"
    .text
    .p2align 4,,15
.globl _Z9smart_xorbb
    .type   _Z9smart_xorbb, @function
_Z9smart_xorbb:
.LFB0:
    .cfi_startproc
    .cfi_personality 0x3,__gxx_personality_v0
    movl    %esi, %eax
    xorl    %edi, %eax
    ret
    .cfi_endproc …
Run Code Online (Sandbox Code Playgroud)

c++ optimization xor

6
推荐指数
2
解决办法
519
查看次数

建议编译器有选择地内联函数调用

假设我有以下代码:

struct Foo {
  void helper() { ... }
  void fast_path() { ...; helper(); ... }
  void slow_path1() { ...; helper(); ... }
  void slow_path2() { ...; helper(); ... }
};
Run Code Online (Sandbox Code Playgroud)

该方法对fast_path()性能至关重要,因此应尽一切努力使其尽可能快.这些方法slow_path1()slow_path2()是不是性能的关键.

根据我的理解,典型的编译器可能会查看此代码并决定不内联helper()是否足够复杂,以减少总指令大小,这helper()在多个方法函数之间共享.helper()如果慢路径方法不存在,那么相同的编译器可能会内联.

鉴于我们期望的性能特征,我们希望编译器内联调用helper()内部fast_path(),但更喜欢编译器在slow_path1()和中的默认行为slow_path2().

一种解决方法是让慢速路径函数定义和调用生成fast_path()在单独的编译单元中,这样编译器就不会看到helper()共享的用法fast_path().但是保持这种分离需要特别小心,不能通过编译器强制执行.此外,文件(Foo.h,FooINLINES.cpp,现在还有Foo.cpp)的扩散是不可取的,并且额外的编译单元使可能只是标题库的构建变得复杂.

有没有更好的办法?

理想情况下,我想要一个新的do_not_inline_function_calls_inside_mec ++关键字,我可以这样使用:

  do_not_inline_function_calls_inside_me void slow_path1() { ... }
  do_not_inline_function_calls_inside_me void slow_path2() { ... }
Run Code Online (Sandbox Code Playgroud)

或者,一个inline_function_calls_inside_me …

c++ inline

6
推荐指数
1
解决办法
163
查看次数

最佳地打包递归模板化结构而不会失去对齐

我有一个由模板参数组成的4个字段的结构:

template <typename T1, typename T2, typename T3, typename T4>
struct __attribute__((aligned(8))) four_tuple {
  typedef struct {
    T1 t1;
    T2 t2;
    T3 t3;
    T4 t4;
  } payload;
  payload p;
};
Run Code Online (Sandbox Code Playgroud)

每种类型T1,T2,T3,和T4,保证是原始类型或four_tuple<...>::payload类型.保证是递归的 - 您可以将结构视为编码其叶节点是基本类型的四叉树.

我的目标是使结构具有最小可能性sizeof,但条件是所有叶节点都正确对齐.允许优化的工具是类模板特化,使用:

  • 字段重新排序t1,t2,t3,t4
  • 添加填料场
  • GCC属性packedpayload
  • 也许其他人?

我觉得使用enable_if和SFINAE 这个问题有一个聪明的解决方案.谁能找到它?

为了说明这个问题,如果我们按原样使用上面的实现,那么using Foo = four_tuple<char,double,char,double>对于有效载荷和整体来说,我们的大小为32.如果我们只是声明有效载荷packed,那么它们double就不会很好地对齐.即重新安排场按递减顺序(在这里,A模板特double, double, char, char …

c++ memory-alignment packed c++11

6
推荐指数
1
解决办法
197
查看次数

已排序的 numpy 数组的交集

我有一个排序的 numpy 数组列表。计算这些数组的排序交集的最有效方法是什么?

在我的应用程序中,我期望数组的数量小于 10^4,我期望单个数组的长度小于 10^7,我期望交集的长度接近 p*N,其中N 是最大数组的长度,其中 0.99 < p <= 1.0。这些数组是从磁盘加载的,如果它们一次不能全部装入内存,则可以分批加载。

一种快速而肮脏的方法是重复调用numpy.intersect1d(). 尽管intersect1d()没有利用数组已排序的事实,但这似乎效率低下。

numpy

6
推荐指数
1
解决办法
1018
查看次数

快速近似浮点除法

在现代处理器上,浮点除法比浮点乘法慢一个数量级(以倒数吞吐量衡量)。

我想知道是否有任何算法可以计算到 的快速近似值x/y,给定某些假设和容差水平。例如,如果您假设0<x<y,并且愿意接受任何在真实值 10% 以内的输出,那么是否有比内置 FDIV 操作更快的算法?

c++ division

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

将提示输入为多种类型的逻辑和

我知道这Union允许您指定多种类型的逻辑或。我想知道是否有办法为逻辑和做类似的事情,例如:

def foo(x: And[Bar, Baz]):
Run Code Online (Sandbox Code Playgroud)

我知道一种选择是明确定义一个继承自Barand的新类型Baz,如下所示:

class BarAndBaz(Bar, Baz):
    ...

def foo(x: BarAndBaz):
Run Code Online (Sandbox Code Playgroud)

在我的上下文中,该选项并不理想。

python python-3.x

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

general expression substitution in sympy

I have two univariate functions, f(x) and g(x), and I'd like to substitute g(x) = y to rewrite f(x) as some f2(y).

Here is a simple example that works:

In [240]: x = Symbol('x')

In [241]: y = Symbol('y')

In [242]: f = abs(x)**2 + 6*abs(x) + 5

In [243]: g = abs(x)

In [244]: f.subs({g: y})
Out[244]: y**2 + 6*y + 5
Run Code Online (Sandbox Code Playgroud)

But now, if I try a slightly more complex example, it fails:

In [245]: h …
Run Code Online (Sandbox Code Playgroud)

sympy

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

优雅地将 int64 的 numpy 数组转换为 datetime64 的 numpy 数组

我有一个代表纳秒x的 dtype numpy 数组np.int64。我可以np.datetime64使用以下代码将其转换为 dtype 的 numpy 数组:

np.array([np.datetime64(int(a), 'ns') for a in x])

有没有更好的方法来做到这一点,避免 python 列表理解?

python numpy python-3.x

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

从 printf 格式字符串中提取类型信息

我想从 printf 格式字符串中提取 C++ 类型信息。例如,

Input: "%10u foo %% %+6.3f %ld %s"

Output:
  unsigned int
  double
  long
  char*
Run Code Online (Sandbox Code Playgroud)

我尝试使用printf.h 中的parse_printf_format()进行此操作 ,但返回的 argtypes 似乎不包含有关签名/未签名的信息。

有没有办法获取签名/未签名信息?

c++ linux printf

2
推荐指数
1
解决办法
2895
查看次数

从协程中提取函数和参数

是否可以在python3.6中提取协程对象的函数和参数?

上下文:目前我有这样的事情:

async def func(*args):
    ...

ret = await remotely(func, x, y)
Run Code Online (Sandbox Code Playgroud)

在幕后,remotelypickles func,xy, scp 的那个到不同的服务器,在那里它解压它们,执行func(x,y),pickles 结果, scp 的那个,最后将它解压到ret.

这个 API 对我来说很讨厌,我更喜欢:

ret = await remotely(func(x, y))
Run Code Online (Sandbox Code Playgroud)

如果我可以腌制由 表示的协程对象func(x, y),我就可以做到这一点,但是当我尝试这样做时,我得到:

TypeError: can't pickle coroutine objects
Run Code Online (Sandbox Code Playgroud)

所以我的备用的希望是,我可以提取fx以及yf(x, y),因此这个问题。

python-asyncio python-3.6

2
推荐指数
1
解决办法
1585
查看次数