我有一个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) 让我们说如果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.
编辑:的确,我的计时代码中出现了一个奇怪的错误,导致了这些结果.当我修复错误时,智能版本按预期更快地结束.我的时间码看起来像这样:
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) 假设我有以下代码:
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 …
我有一个由模板参数组成的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,t4packed上payload我觉得使用enable_if和SFINAE 这个问题有一个聪明的解决方案.谁能找到它?
为了说明这个问题,如果我们按原样使用上面的实现,那么using Foo = four_tuple<char,double,char,double>对于有效载荷和整体来说,我们的大小为32.如果我们只是声明有效载荷packed,那么它们double就不会很好地对齐.即重新安排场按递减顺序(在这里,A模板特double, double, char, char …
我有一个排序的 numpy 数组列表。计算这些数组的排序交集的最有效方法是什么?
在我的应用程序中,我期望数组的数量小于 10^4,我期望单个数组的长度小于 10^7,我期望交集的长度接近 p*N,其中N 是最大数组的长度,其中 0.99 < p <= 1.0。这些数组是从磁盘加载的,如果它们一次不能全部装入内存,则可以分批加载。
一种快速而肮脏的方法是重复调用numpy.intersect1d(). 尽管intersect1d()没有利用数组已排序的事实,但这似乎效率低下。
在现代处理器上,浮点除法比浮点乘法慢一个数量级(以倒数吞吐量衡量)。
我想知道是否有任何算法可以计算到 的快速近似值x/y,给定某些假设和容差水平。例如,如果您假设0<x<y,并且愿意接受任何在真实值 10% 以内的输出,那么是否有比内置 FDIV 操作更快的算法?
我知道这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)
在我的上下文中,该选项并不理想。
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) 我有一个代表纳秒x的 dtype numpy 数组np.int64。我可以np.datetime64使用以下代码将其转换为 dtype 的 numpy 数组:
np.array([np.datetime64(int(a), 'ns') for a in x])
有没有更好的方法来做到这一点,避免 python 列表理解?
我想从 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 似乎不包含有关签名/未签名的信息。
有没有办法获取签名/未签名信息?
是否可以在python3.6中提取协程对象的函数和参数?
上下文:目前我有这样的事情:
async def func(*args):
...
ret = await remotely(func, x, y)
Run Code Online (Sandbox Code Playgroud)
在幕后,remotelypickles func,x和y, 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)
所以我的备用的希望是,我可以提取f,x以及y从f(x, y),因此这个问题。