当使用openmp的parallel for construct分配和释放具有4个或更多线程的随机大小的内存块时,程序似乎开始在测试程序的运行时的后半部分泄漏大量内存.因此,它消耗的内存从1050 MB增加到1500 MB或更多,而无需实际使用额外的内存.
由于valgrind没有显示任何问题,我必须假设看起来像是内存泄漏实际上是内存碎片的强调效果.
有趣的是,如果2个线程分别进行10000次分配,则效果尚未显示,但如果4个线程分别进行5000次分配则显示效果很强.此外,如果分配的块的最大大小减少到256kb(从1mb),则效果会变弱.
重型并发能否强调碎片那么多?或者这更可能是堆中的错误?
构建演示程序是为了从堆中获取总共256 MB的随机大小的内存块,进行5000次分配.如果达到内存限制,则首先分配的块将被释放,直到内存消耗低于限制.执行5000次分配后,将释放所有内存并结束循环.所有这些工作都是针对openmp生成的每个线程完成的.
这种内存分配方案允许我们预计每个线程的内存消耗约为260 MB(包括一些簿记数据).
由于这是您可能想要测试的内容,您可以使用dropbox中的简单makefile下载示例程序.
按原样运行程序时,您应该至少有1400 MB的RAM可用.您可以随意调整代码中的常量以满足您的需求.
为完整起见,实际代码如下:
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <vector>
#include <deque>
#include <omp.h>
#include <math.h>
typedef unsigned long long uint64_t;
void runParallelAllocTest()
{
// constants
const int NUM_ALLOCATIONS = 5000; // alloc's per thread
const int NUM_THREADS = 4; // how many threads?
const int NUM_ITERS = NUM_THREADS;// how many overall repetions
const bool USE_NEW = true; // …Run Code Online (Sandbox Code Playgroud) 在Go中,复制切片是标准费用,如下所示:
# It will figure out the details to match slice sizes
dst = copy(dst[n:], src[:m])
Run Code Online (Sandbox Code Playgroud)
在Rust中,我找不到与替换类似的方法.我想出的东西看起来像这样:
fn copy_slice(dst: &mut [u8], src: &[u8]) -> usize {
let mut c = 0;
for (&mut d, &s) in dst.iter_mut().zip(src.iter()) {
d = s;
c += 1;
}
c
}
Run Code Online (Sandbox Code Playgroud)
不幸的是,我得到了这个我无法解决的编译错误:
error[E0384]: re-assignment of immutable variable `d`
--> src/main.rs:4:9
|
3 | for (&mut d, &s) in dst.iter_mut().zip(src.iter()) {
| - first assignment to `d`
4 | d = s;
| ^^^^^ re-assignment …Run Code Online (Sandbox Code Playgroud) 以下内容仅用作示例,而不是有效的Rust代码.
struct Vec<T: Sized, Count> {
a: [T; Count]
}
Run Code Online (Sandbox Code Playgroud)
在C++模板中可能有类似的东西,但我还没有在Rust中看到它.
我试图获得一个动态可调度的借用实现两个Reader和的对象的实例Seek.
据我所知,只要涉及一个特征,Rust就可以进行动态调度.
use std::io::{Read, Seek};
fn user(stream: &mut Read) {}
Run Code Online (Sandbox Code Playgroud)
但是,有两个或更多特征边界,我被迫使用类型参数:
fn user_gen<T: Read + Seek>(stream: &mut T) {}
Run Code Online (Sandbox Code Playgroud)
由于下面的实际类型是构建器,它必须以某种方式存储借用的对象,并且使用类型参数将使实现更复杂(我已经有三个类型参数).
理想情况下,我可以做这样的事情:
fn user_dynamic(stream: &mut (Read + Seek)) {}
Run Code Online (Sandbox Code Playgroud)
这不编译:
error[E0225]: only auto traits can be used as additional traits in a trait object
--> src/main.rs:3:38
|
3 | fn user_dynamic(stream: &mut (Read + Seek)) {}
| ^^^^ non-auto additional trait
Run Code Online (Sandbox Code Playgroud)
我知道动态调度是通过胖指针完成的,通常它们只引用一个方法表,而不是多个方法表.我还没有看到过支持这种语言的静态编译语言,但这样的功能对我有很大帮助.
当试图运行构建一个大的程序clap::App(在这里找到源代码)时,我得到一个stackoverflow : thread '<main>' has overflowed its stack.
到目前为止,我无法弄清楚如何指示rustc增加堆栈大小的强力解决方法.RUST_MIN_STACK似乎只适用于运行时,即使它似乎没有任何影响.
在生成代码时,我可能要做的就是将SubCommand创建移动到运行时,这是我接下来要尝试的.
但是,您是否看到了以不同方式解决此问题的方法?
如果构建的模式看起来容易出现这个问题,那么构建这个问题似乎非常重要,如果构建的结构只是很大并且足够嵌套.
git clone -b clap https://github.com/Byron/google-apis-rs
cd google-apis-rs
git checkout 9a8ae4b
make dfareporting2d1-cli-cargo ARGS=run
Run Code Online (Sandbox Code Playgroud)
请注意,您将需要我的准叉并在本地设置覆盖以允许使用最新的编译器进行构建.
? google-apis-rs git:(clap) rustc --version
rustc 1.1.0-nightly (97d4e76c2 2015-04-27) (built 2015-04-28)
Run Code Online (Sandbox Code Playgroud) 以下代码显示问题的来源.由于as_slice()已弃用,as_ref()建议更换.
但是,在此上下文中使用它时,需要类型注释.
let s = "Hi"; // This is a string slice
// warning: use of deprecated item: use std::convert::AsRef<str> instead, #[warn(deprecated)] on by default
assert!(s.replace("Hi", "Ho").as_slice() == "Ho");
// tests/lang.rs:120:35: 120:43 error: type annotations required: cannot resolve `collections::string::String : core::convert::AsRef<_>` [E0283]
// assert!(s.replace("Hi", "Ho").as_ref() == "Ho");
Run Code Online (Sandbox Code Playgroud)
我怎样才能提供这样的类型注释?.我觉得唯一适用的语法是<MyType as AsRef>::as_ref(),但我不知道如何用实例做到这一点.
我在用rustc 1.0.0-nightly (be9bd7c93 2015-04-05) (built 2015-04-05).
当按照相应博客文章的建议使用稳定的serde时,必须使用内置宏来提取由serde-codegen生成的文件.include!
这里链接的文件在一个更复杂的例子中显示了这个,它可以使用rustc nightly和rustc stable.
然而,正如建议的文档include!,它不卫生行为.
这意味着我不清楚,直到我遇到一个问题,即在外部包中定义的宏,yup-hyper-mock,没有在包含时定义.一些测试表明即使是类似的东西extern crate foo-bar-snoo-snoo;也不会在包含时触发错误,表明它还没有被评估过.
问题来自于include!尝试扩展宏,如果这些宏来自尚未评估的外部包装箱,则会失败.
我尝试使用正确的签名来定义空宏会导致include!宏工作,但编译会在以后失败,因为include!实际上会立即扩展宏,这在包含时是空的.
有没有办法include!在外部板条箱中定义宏?或者,你能想象一个解决方法来使我的特定案例有效吗?
我个人认为include!根本不应该扩展宏,但是将其留给下一个应该引入外部包装箱的编译步骤 - 也许我们正在查看一个错误rustc,但我不确定.
请注意,稳定和夜间编译器都显示相同的问题.
git clone --branch syntex https://github.com/Byron/yup-oauth2
cd yup-oauth2
git reset --hard f59d97d
# build and test fail because 'include!' runs before crates are …Run Code Online (Sandbox Code Playgroud) 我经常发现自己编写的代码如下:
myvec.iter().map(|x| some_operation(x)).count()
Run Code Online (Sandbox Code Playgroud)
调用count会触发要使用的迭代器链,但也会产生非单位结果,这是不希望的.
我正在寻找类似的东西
myvec.iter().map(|x| some_operation(x)).consume()
Run Code Online (Sandbox Code Playgroud)
这相当于
for _ in myvec.iter().map(|x| some_operation(x)) {}
Run Code Online (Sandbox Code Playgroud) 下面的代码最能说明问题.
use std::iter::IntoIterator;
fn iterate<I: IntoIterator<Item=String>>(v: I) {
}
// iterate(&["foo".to_string()])
// error: type mismatch resolving `<&[collections::string::String; 1] as core::iter::IntoIterator>::Item == collections::string::String`:
// expected &-ptr,
// found struct `collections::string::String` [E0271]
// iterate(["foo".to_string()].iter())
// type mismatch resolving `<core::slice::Iter<'_, collections::string::String> as core::iter::IntoIterator>::Item == collections::string::String`:
// expected &-ptr,
// found struct `collections::string::String` [E0271]
// This works !
iterate(vec!["foo".to_string()])
Run Code Online (Sandbox Code Playgroud)
如何一般地迭代任何东西(使用给定的项目类型)?
目的是允许这样的函数的用户传入可以迭代或转换为迭代器的任何东西.
此外,我感觉实际问题并没有在编译器错误中真正描述 - 因为它看到的类型似乎与它显示的不同.
我在用 rustc 1.0.0-nightly (522d09dfe 2015-02-19) (built 2015-02-19)
目前,SliceConcatExt似乎非常专门为字符串的切片或向量而精心设计,即使它任意限制其使用.这个特定的用例也反映在特征名称中,毕竟,它被调用SliceConcatExt是有原因的.
是否有一个更通用的connect()实现,可以将任何Iterator用于支持Str特性的项目?.如果没有,有没有计划补救这个?
use std::iter::IntoIterator;
fn connected<S, I>(s: I) -> String
where S: Str,
I: IntoIterator<Item=S> {
// have
s.into_iter().collect::<Vec<S>>().connect(", ")
// want
// s.into_iter().connect(", ")
// error: type `<I as core::iter::IntoIterator>::IntoIter` does not implement any method in scope named `connect`
// tests/lang.rs:790 s.into_iter().connect(", ")
}
connected(&["foo", "bar"]);
Run Code Online (Sandbox Code Playgroud)
有人可能会对SliceConcatExt项目类型为Str的任何迭代器实现,但我怀疑connect()目前只是不必要的专业化,在Rust beta之前可能是可以修复的.
运用 rustc 1.0.0-nightly (522d09dfe 2015-02-19) (built 2015-02-19)