我试图在逗号是小数分隔符的德国语言环境中一起使用 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) 作为我的问题的后续问题在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)
但是应该考虑一些事情.
NI>10^7),则循环的整个内容不适合指令高速缓存,因此必须一遍又一遍地加载,使得RAM的速度定义执行所需的时间.例如,对于大的内部部分,xorl %eax, %eax(2个字节)比xorq %rax, %rax(3个字节)快33%.NI是小,整个循环可轻松放入指令缓存,比xorl %eax, %eax和xorq %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)
结果是:
NI>10^4),我测量4.2 ns/ - jmp指令(相当于从RAM加载的42个字节或在我的机器上大约12个时钟周期).NI<10^3),我测量1 ns/jmp-指令(大约3个时钟周期,听起来似乎合理--Agner Fog的表显示了2个时钟周期的成本).该指令jmp LX使用2字节eb 00 …
我正在 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) 作为自我教育项目的一部分,我研究了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?
movups我应该使用的旁边的用法-O3?movups我不知道有什么缺点?更多上下文:我尝试比较两个可能的函数签名:
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 源文件编译的重定位表的条目时遇到了一些问题。我的程序如下:
//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.c和ld 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 ++ 11起,可能会发生以下情况之一,假设已定义了移动构造函数和复制构造函数(另请参见本文结尾处的示例):
前3种情况的建议不要使用显式std::move,因为无论如何执行移动都可能会阻止可能的RVO,例如参见此SO-post。
但是,在4.情况下,显式std::move可以提高性能。但是,由于有些人既不懂标准又不懂汇编程序,所以需要花很多时间来区分情况1-3和4。
因此,我的问题是:有没有一种方法可以统一处理上述所有情况,例如:
这是一些示例,也可以用作测试用例。
所有示例都使用以下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) 在即将到来的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)
但是3str,3语言级别和语言级别之间有什么区别?对于哪些代码,使用语言级别3str和3语言级别编译的模块的行为会有所不同吗?
当我使用命令在 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) 该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) 考虑以下带有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 …