小编ead*_*ead的帖子

stod 不能与 boost::locale 一起正常工作

我试图在逗号是小数分隔符的德国语言环境中一起使用 boost::locale 和 std::stod 。考虑这个代码:

boost::locale::generator gen;

std::locale loc("");  // (1)
//std::locale  loc = gen("");  // (2)

std::locale::global(loc);
std::cout.imbue(loc);

std::string s = "1,1";  //float string in german locale!
double d1 = std::stod(s);
std::cout << "d1: " << d1 << std::endl;

double d2 = 2.2;
std::cout << "d2: " << d2 << std::endl;
Run Code Online (Sandbox Code Playgroud)

std::locale loc("") 创建正确的语言环境,输出为

d1: 1,1
d2: 2,2
Run Code Online (Sandbox Code Playgroud)

正如我所料。当我注释掉第 (1) 行和取消注释第 (2) 行时,输出是

d1: 1
d2: 2.2
Run Code Online (Sandbox Code Playgroud)

d2 的结果在意料之中。据我了解 boost::locale 希望我明确指定 d2 应该被格式化为一个数字并做

std::cout << "d2: " << boost::locale::as::number …
Run Code Online (Sandbox Code Playgroud)

c++ boost locale boost-locale

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

缓慢的jmp指令

作为我的问题后续问题在x86-64中使用32位寄存器/指令的优点,我开始测量指令的成本.我知道这已经多次完成了(例如Agner Fog),但我这样做是为了娱乐和自我教育.

我的测试代码非常简单(为简单起见,这里是伪代码,实际上是汇编程序):

for(outer_loop=0; outer_loop<NO;outer_loop++){
    operation  #first
    operation  #second
    ...
    operation #NI-th
} 
Run Code Online (Sandbox Code Playgroud)

但是应该考虑一些事情.

  1. 如果循环的内部部分很大(大NI>10^7),则循环的整个内容不适合指令高速缓存,因此必须一遍又一遍地加载,使得RAM的速度定义执行所需的时间.例如,对于大的内部部分,xorl %eax, %eax(2个字节)比xorq %rax, %rax(3个字节)快33%.
  2. 如果NI是小,整个循环可轻松放入指令缓存,比xorl %eax, %eaxxorq %rax, %rax同样快速,可以执行每时钟周期的4倍.

然而,这个简单的模型并没有为jmp建筑提供水.对于jmp-instruction,我的测试代码如下所示:

for(outer_loop=0; outer_loop<NO;outer_loop++){
    jmp .L0
    .L0: jmp .L1
    L1: jmp L2
    ....
}
Run Code Online (Sandbox Code Playgroud)

结果是:

  1. 对于"大"循环大小(已经用于NI>10^4),我测量4.2 ns/ - jmp指令(相当于从RAM加载的42个字节或在我的机器上大约12个时钟周期).
  2. 对于小环路尺寸(NI<10^3),我测量1 ns/jmp-指令(大约3个时钟周期,听起来似乎合理--Agner Fog的表显示了2个时钟周期的成本).

该指令jmp LX使用2字节eb 00 …

performance x86 assembly intel cpu-architecture

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

Cython 编译将文本附加到文件名中,如何摆脱它?

我正在 Ubuntu 平台上使用 cython。一切都很好,除了一件事让我烦恼。将 cython 项目编译为 .so 文件时,.pyx 文件的文件名会附加“cpython-36m-x86_64-linux-gnu”。例如,如果我构建“helloworld.pyx”,则生成的 .so 文件称为:“helloworld.cpython-36m-x86_64-linux-gnu.so”。然而,我只想将其命名为“helloworld.so”。

我认为答案是相当微不足道的,所以我开始谷歌搜索,即使在 30 分钟后我也找不到任何关于这个主题的信息。有人有什么主意吗?

这是我的 .pyx 文件:

print('hello world')
Run Code Online (Sandbox Code Playgroud)

setup.py 文件:

from distutils.core import setup
from Cython.Build import cythonize

setup(
    ext_modules = cythonize("helloworld.pyx")
)
Run Code Online (Sandbox Code Playgroud)

构建文件:

python setup.py build_ext --inplace
Compiling helloworld.pyx because it changed.
[1/1] Cythonizing helloworld.pyx
running build_ext
building 'helloworld' extension
gcc -pthread -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -fPIC -I/home/**/anaconda3/include/python3.6m -c helloworld.c -o build/temp.linux-x86_64-3.6/helloworld.o
gcc -pthread -shared -L/home/**/anaconda3/lib -Wl,-rpath=/home/ed/anaconda3/lib,--no-as-needed build/temp.linux-x86_64-3.6/helloworld.o -L/home/**/anaconda3/lib -lpython3.6m -o /home/**/new_project/helloworld.cpython-36m-x86_64-linux-gnu.so
Run Code Online (Sandbox Code Playgroud)

python gcc distutils cython cythonize

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

g ++处理复制std :: complex

作为自我教育项目的一部分,我研究了g ++如何处理std::complex- 类型,并对这个简单的函数感到困惑:

#include <complex>  
std::complex<double> c;

void get(std::complex<double> &res){
    res=c;
}
Run Code Online (Sandbox Code Playgroud)

用Linux64 编译g++-6.3 -O3(或者也是-Os)我得到了这个结果:

    movsd   c(%rip), %xmm0
    movsd   %xmm0, (%rdi)
    movsd   c+8(%rip), %xmm0
    movsd   %xmm0, 8(%rdi)
    ret
Run Code Online (Sandbox Code Playgroud)

因此它将实部和虚部单独移动为64位浮点数.但是,我希望程序集使用两个movups而不是四个movsd,即同时将实部和虚部移动为128位包:

    movups  c(%rip), %xmm0
    movups  %xmm0, (%rdi)
    ret
Run Code Online (Sandbox Code Playgroud)

这不仅是我的机器(英特尔Broadwell)的两倍 - movsd反转,而且只需要16个字节,而movsd-version需要36个字节.

g ++创建程序集的原因是什么movsd

  1. 还有一个额外的编译器标志来触发movups我应该使用的旁边的用法-O3
  2. 使用movups我不知道有什么缺点?
  3. g ++在这里不会产生最佳装配?
  4. 别的什么?

更多上下文:我尝试比较两个可能的函数签名:

std::complex<double> get(){
    return c;
}
Run Code Online (Sandbox Code Playgroud)

void get(std::complex<double> &res){
    res=c;
}
Run Code Online (Sandbox Code Playgroud)

由于SystemV …

c++ assembly gcc

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

目标文件重定位表中条目的含义

我在理解从 C 源文件编译的重定位表的条目时遇到了一些问题。我的程序如下:

//a.c
extern int shared;
int main(){
    int a = 100;
    swap(&a, &shared);
    a = 200;
    shared = 1;
    swap(&a, &shared);
}
//b.c
int shared = 1;
void swap(int* a, int* b) {
    if (a != b)
        *b ^= *a ^= *b, *a ^= *b;
}
Run Code Online (Sandbox Code Playgroud)

我使用以下命令gcc -c -fno-stack-protector a.c b.cld a.o b.o -e main -o ab. 然后我objdump -r a.o检查它的重定位表。

RELOCATION RECORDS FOR [.text]:
OFFSET           TYPE              VALUE 
0000000000000014 R_X86_64_32       shared
0000000000000021 R_X86_64_PC32 …
Run Code Online (Sandbox Code Playgroud)

c linker x86-64 relocation

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

如何确保在不妨碍RVO的情况下移动?

从函数返回对象时,自C ++ 11起,可能会发生以下情况之一,假设已定义了移动构造函数和复制构造函数(另请参见本文结尾处的示例):

  1. 具有复制删除资格,并且编译器执行RVO。
  2. 它有资格进行复制删除,并且编译器不执行RVO,但是...
  3. 有资格使用move构造函数并被移动。
  4. 以上都不是,并且使用了复制构造函数。

前3种情况的建议不要使用显式std::move,因为无论如何执行移动都可能会阻止可能的RVO,例如参见此SO-post

但是,在4.情况下,显式std::move可以提高性能。但是,由于有些人既不懂标准又不懂汇编程序,所以需要花很多时间来区分情况1-3和4。

因此,我的问题有没有一种方法可以统一处理上述所有情况,例如:

  1. 不阻止RVO(情况1)
  2. 如果未执行RVO,则使用move-constructor(情况2、3和4)
  3. 如果没有移动构造函数,则应将复制构造函数用作后备。

这是一些示例,也可以用作测试用例。

所有示例都使用以下helper-class-definition:

struct A{
    int x;
    A(int x_);
    A(const A& a);
    A(A&& a);
    ~A();
};
Run Code Online (Sandbox Code Playgroud)

1.示例: 1.case,RVO执行,现场演示结果汇编程序

A callee1(){
    A a(0);
    return a;
}
Run Code Online (Sandbox Code Playgroud)

2.示例: 1.case,RVO执行,现场演示结果汇编程序

A callee2(bool which){
    return which? A(0) : A(1);
}
Run Code Online (Sandbox Code Playgroud)

3.示例: 2.case,有资格进行复制删除,未执行RVO,现场演示结果汇编程序

A callee3(bool which){ …
Run Code Online (Sandbox Code Playgroud)

c++ language-lawyer rvo c++11

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

Cython的language_level 3和3str有什么区别?

在即将到来的Cython 3.0版本中,3strlanguage_level(由Cython 0.29引入)成为新的默认值,而不是当前的默认值2,即,如果未设置language_level(如何设置),则会收到以下警告:

FutureWarning:未设置Cython指令'language_level',暂时使用'3str'(Py3)。这与以前的版本有所不同!文件:/home/ed/mygithub/cython/foo.pyx tree = Parsing.p_module(s,pxd,full_module_name)

但是3str3语言级别和语言级别之间有什么区别?对于哪些代码,使用语言级别3str3语言级别编译的模块的行为会有所不同吗?

python cython

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

如何在 Windows 上使用 cython 编译 __init__.py 文件

当我使用命令在 Windows 上编译任意 __init__.py 文件时setup.py build_ext --inplace,它出现无法解析的外部符号错误(即“LINK:错误 LNK2001:无法解析的外部符号 PyInit___init__”)。

当地环境:

python3.7,
Cython 0.29.14,
window10 x64,
Microsoft Visual Studio 2017,
Run Code Online (Sandbox Code Playgroud)

ctest/__init__.py

# cython: language_level=3
print('__init__')

Run Code Online (Sandbox Code Playgroud)

安装程序.py

python3.7,
Cython 0.29.14,
window10 x64,
Microsoft Visual Studio 2017,
Run Code Online (Sandbox Code Playgroud)

终端打印的信息:

Compiling ctest/__init__.py because it changed.
[1/1] Cythonizing ctest/__init__.py
running build_ext
building 'ctest.__init__' extension
creating build
creating build\temp.win-amd64-3.7
creating build\temp.win-amd64-3.7\Release
creating build\temp.win-amd64-3.7\Release\ctest
C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.16.27023\bin\HostX86\x64\cl.exe /c /nologo /Ox /W3 /GL /DNDEBUG /MD -Id:\py37\include -Id:\py37\incl
ude "-IC:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.16.27023\include" "-IC:\Program Files …
Run Code Online (Sandbox Code Playgroud)

python windows cython

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

如何替换已弃用的 imp.load_dynamic 的用法?

imp模块已被弃用(自版本 3.4 起),但是基础设施的某些部分(例如pyximport)仍然使用imp.load_dynamic,这会导致较新的 Python 版本出现弃用警告。

在内部,imp.load_dynamic使用importlib-machinery

from importlib._bootstrap import _load
def load_dynamic(name, path, file=None):
    """**DEPRECATED**
    Load an extension module.
    """
    import importlib.machinery
    loader = importlib.machinery.ExtensionFileLoader(name, path)

    # Issue #24748: Skip the sys.modules check in _load_module_shim;
    # always load new extension
    spec = importlib.machinery.ModuleSpec(
        name=name, loader=loader, origin=path)
    return _load(spec)
Run Code Online (Sandbox Code Playgroud)

但为所有类型的项目重复此代码(至少需要改进一次)感觉很愚蠢。

importlib的文档提出以下建议:

import importlib.util
import sys
def alternative_load_dynamic(name, path, file=None):
    spec = importlib.util.spec_from_file_location(name, path)
    module = importlib.util.module_from_spec(spec) …
Run Code Online (Sandbox Code Playgroud)

python python-3.x python-importlib

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

C和C++中inline-keyword的区别

考虑以下带有inline-function 的C++ 代码:

// this function is in a header-file:
// recursion prevents inlining
inline int calc(int k){
    if(k<=1) return 1;
    return calc(k-1)+calc(k-2);
}

// this function is in a source-file:
int fun(int k){
    return calc(k);
}
Run Code Online (Sandbox Code Playgroud)

这里我使用递归来模拟编译器无法内联函数的情况calc

生成的程序集(使用 编译-Os,请参阅https://godbolt.org/ 上的直播):

...
        .weak   calc(int)
        .type   calc(int), @function
calc(int):
    // some assembler


       .text
        .globl  fun(int)
        .type   fun(int), @function
fun(int):
...
        jmp     calc(int)
Run Code Online (Sandbox Code Playgroud)

正如预期的那样,编译器无法内联calc,因此为它发出了代码,但由于inline-keyword 它变成了一个弱符号。

编译与 C 相同的代码,会产生不同的结果(使用-Os,see …

c c++ language-lawyer

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