小编OMG*_*chy的帖子

删除 Rust 循环中的边界检查以尝试达到最佳编译器输出

为了确定我是否可以/应该使用 Rust 而不是默认的 C/C++,我正在研究各种边缘情况,主要考虑到这个问题:在 0.1% 的情况下,它确实很重要,我总能得到编译器输出与 gcc 一样好(具有适当的优化标志)?答案很可能是否定的,但让我们看看......

Reddit上有一个相当特殊的示例,研究无分支排序算法的子例程的编译器输出。

这是基准 C 代码:

#include <stdint.h>
#include <stdlib.h>
int32_t* foo(int32_t* elements, int32_t* buffer, int32_t pivot)
{
    size_t buffer_index = 0;

    for (size_t i = 0; i < 64; ++i) {
        buffer[buffer_index] = (int32_t)i;
        buffer_index += (size_t)(elements[i] < pivot);
    }
}
Run Code Online (Sandbox Code Playgroud)

这是带有编译器输出的godbolt 链接

Rust 的第一次尝试如下所示:

pub fn foo0(elements: &Vec<i32>, mut buffer: [i32; 64], pivot: i32) -> () {
    let mut buffer_index: usize = 0;
    for i in 0..buffer.len() {
        buffer[buffer_index] …
Run Code Online (Sandbox Code Playgroud)

loops rust bounds-check-elimination

10
推荐指数
1
解决办法
4871
查看次数

为什么可以在ARMv8上使用xzr寄存器而不是文字0?

我正在阅读ARM发布的SVE白皮书,并发现了令我印象深刻的东西(在非SVE示例中):

mov x8, xzr
Run Code Online (Sandbox Code Playgroud)

我不知道这个xzr寄存器是什么,所以我查了一下,发现ARM的一些内容,说它在很多情况下都是零的同义词.

所以看起来x8它被初始化为零,这是有道理的,因为它在循环之前执行,x8用作循环计数器.

我不明白的是,为什么不使用文字0而不是xzr?例如:

mov x8, 0
Run Code Online (Sandbox Code Playgroud)

总而言之,我的问题是:为什么可以使用xzr寄存器而不是文字0

assembly arm armv8

8
推荐指数
2
解决办法
3868
查看次数

在boost :: signals2中混合使用boost智能指针和C++ 11智能指针

我有一个用于boost::signals2组件之间通信的应用程序.我正在尝试使用它的自动连接管理功能slot_type(...).track(weak_ptr).

问题:

在我的整个程序中,std::shared_ptr使用..track期待一个boost::weak_ptr,我提供一个std::weak_ptr.

这是我得到的确切错误:

cannot convert argument 1 from 'std::weak_ptr<_Ty>' to 'const boost::weak_ptr<void> &'
Run Code Online (Sandbox Code Playgroud)

这有解决方法吗?或者我误解了这个问题?

c++ boost c++11

7
推荐指数
1
解决办法
362
查看次数

C#vs C++中的新操作符

来自C++,我对new在C#中使用关键字感到困惑.

我知道它不像C++一样工作new,因为你不必手动控制对象的生命周期,因为C#有垃圾收集.

但是,当阅读其他人的C#代码时,我会注意到代码片段1中的语句.如果new在代码片段2 中完全避免使用它会不会更容易?

片段1

Foo fooInstance = new Foo();
Run Code Online (Sandbox Code Playgroud)

片段2

Foo fooInstance;
Run Code Online (Sandbox Code Playgroud)

我的问题是,代码段1和代码段2之间有什么区别,为什么我更喜欢一个呢?

c# c++ new-operator

7
推荐指数
2
解决办法
2837
查看次数

退出系统调用的正确常量是什么?

我正在尝试学习 x86_64 汇编,并使用 GCC 作为我的汇编程序。我正在使用的确切命令是:

gcc -nostdlib tapydn.S -D__ASSEMBLY__
Run Code Online (Sandbox Code Playgroud)

我主要使用 gcc 作为它的预处理器。这是tapydn.S

.global _start

#include <asm-generic/unistd.h>

syscall=0x80

.text
_start:
    movl $__NR_exit, %eax
    movl $0x00, %ebx
    int  $syscall
Run Code Online (Sandbox Code Playgroud)

这会导致分段错误。我相信问题出在以下几行:

 movl $__NR_exit, %eax
Run Code Online (Sandbox Code Playgroud)

我使用__NR_exit它是因为它比一些神奇的数字更具描述性。但是,我对它的使用似乎是不正确的。我相信情况确实如此,因为当我将有问题的行更改为以下内容时,它运行良好:

movl $0x01, %eax
Run Code Online (Sandbox Code Playgroud)

进一步支持这一思路的是以下内容usr/include/asm-generic/unistd.h

#define __NR_exit 93
__SYSCALL(__NR_exit, sys_exit)
Run Code Online (Sandbox Code Playgroud)

我预计 __NR_exit 的值为 1,而不是 93!显然我误解了它的目的,因此误解了它的用法。据我所知,我很幸运能在$0x01案例中工作(很像 C++ 中的未定义行为),所以我一直在挖掘......

接下来,我寻找sys_exit. 我找不到。我尝试使用它如下(有和没有前面的 $):

movl $sys_exit, %eax
Run Code Online (Sandbox Code Playgroud)

这不会链接:

/tmp/cc7tEUtC.o: In function `_start':
(.text+0x1): undefined reference to `sys_exit'
collect2: error: ld returned 1 exit …
Run Code Online (Sandbox Code Playgroud)

assembly gcc x86-64

7
推荐指数
1
解决办法
2286
查看次数

给定一个包含lambda函数的调用堆栈,如何确定其来源?

假设你有一些代码推送到这样的队列:

template <typename T>
void submitJobToPool(T callable)
{
    someJobQueue.push(callable)
}
Run Code Online (Sandbox Code Playgroud)

......以及后来:

template <typename T>
void runJobFromPool(T callable)
{
    auto job = someJobQueue.pop();
    job();
}
Run Code Online (Sandbox Code Playgroud)

现在想象一下,由于job()调用内部的一些错误,代码崩溃了.如果提交的作业是普通函数,则调用堆栈可能如下所示:

void myFunction()     0x345678901
void runJobFromPool() 0x234567890
int main(int, char**) 0x123456789
Run Code Online (Sandbox Code Playgroud)

很容易看出这里崩溃了什么功能.如果它是一个仿函数,它将是相似的,但operator()在某处(忽略内联).然而,对于一个lambda ......

void lambda_a7009ccf8810b62b59083b4c1779e569() 0x345678901
void runJobFromPool()                          0x234567890
int main(int, char**)                          0x123456789
Run Code Online (Sandbox Code Playgroud)

这不是那么容易调试.如果在发生调试器时附加了调试器,或者核心转储可用,则可以使用该信息来导出哪个lambda崩溃,但该信息并不总是可用.据我所知,反汇编是确定从此崩溃的几种方法之一.

我必须做的更好的想法是:

  1. 使用addr2line平台支持的工具.这有时有效,有时不行.
  2. 用算子包裹所有的lambda(不是理想的,至少可以说).
  3. 不使用lambdas(再次,不理想).
  4. 使用编译器扩展为lambda提供更有意义的名称/添加调试信息.

第四个选项听起来很有希望,所以我做了一些调查,但找不到任何东西.如果它很重要,我可用的编译器是clang ++ 5.0和MSVC 19(Visual Studio 2015).

我的问题是,有哪些其他工具/技术可以帮助将带有lambda函数的callstack映射到相应的源代码行?

c++ debugging lambda

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

试图将向量的内容传递给线程

我有一个带字符串向量的函数,我在向量中有一系列字符串向量.

我想循环遍历将每个字符串向量传递给新线程的向量.

for (vector<vector<string> >::iterator it = vecstringvec.begin() ; 
     it != vecstringvec.end(); ++it){
    threadvector.push_back(thread(func, *it));
}
Run Code Online (Sandbox Code Playgroud)

基本上是上面的,除了上面的不起作用(编译错误).我相信我需要一个传递的std :: ref来传递,但我不确定,或者如何使用迭代器来做到这一点.

完整错误:

/usr/include/c++/4.8/functional: In instantiation of ‘struct std::_Bind_simple<void (*(std::vector<std::basic_string<char> >, std::reference_wrapper<std::vector<std::basic_string<char> > >))(std::vector<std::basic_string<char> >&, std::vector<std::basic_string<char> >&)>’:
/usr/include/c++/4.8/thread:137:47:   required from ‘std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = void (&)(std::vector<std::basic_string<char> >&, std::vector<std::basic_string<char> >&); _Args = {std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >&, std::reference_wrapper<std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >}]’
prog.cpp:199:55:   required from here
/usr/include/c++/4.8/functional:1697:61: error: no type named …
Run Code Online (Sandbox Code Playgroud)

c++

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

CRTP基类型使用的成员变量应该是派生类型吗?

我今天一直在学习CRTP(奇怪的重复模板模式),并相信我理解得很好.

但是,在我看到的示例中,状态存储在派生类型中,即使基类型依赖于它们的存在.对我来说,这似乎是不合逻辑的,成员变量应该在基类型中,因为它的功能依赖于它们.

这是我正在谈论的一个简单例子:

template <typename DerivedType>
class Base{
public:
    int calculate() {
        return static_cast<DerivedType&>(*this).x + static_cast<DerivedType&>(*this).y;
    }
};

class Derived : Base<Derived>{
public:
    int x; // ignore the fact that these aren't initialised for simplicity
    int y;
};
Run Code Online (Sandbox Code Playgroud)

我的问题是:

我是否正确地认为成员x并且y在基类型方面会更好?如果没有,为什么?

c++ crtp

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

将(0,1)更改为(0,1)而不进行分支

我有一个输出值的随机数生成器(0, 1],但是我需要将输出提供给一个在0或1处返回无穷大的函数.如何在(0, 1)没有任何分支的情况下对生成的数字进行后处理,因为这是为了在GPU上执行?

我想一种方法是添加一个小常数然后取值mod 1.换句话说,生成from (?, 1 + ?],变成了[?, 1).有没有更好的办法?应该?是什么?

random floating-point haskell

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

模式匹配数字字符串

我有一个模式匹配其参数的函数,它是string:

let processLexime lexime
    match lexime with
    | "abc" -> ...
    | "bar" -> ...
    | "cat" -> ...
    | _     -> ...
Run Code Online (Sandbox Code Playgroud)

这按预期工作.但是,我现在试图通过表达"匹配string仅包含以下字符" 来扩展它.在我的具体示例中,我希望只匹配包含数字的任何内容.

我的问题是,我怎样才能在F#中表达这一点?我更喜欢在没有任何库的情况下这样做FParsec,因为我主要是为了学习目的而这样做.

f# pattern-matching

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