我正在尝试编写一些SIMD,主要用于学习目的.我知道Go可以链接汇编,但我无法让它正常工作.
这是我可以做的最小的例子(元素向量乘法):
vec_amd64.s(注意:实际文件下面有一个空白行,RET因为它会导致错误)
// func mul(v1, v2 Vec4) Vec4
TEXT .mul(SB),4,$0-48
MOVUPS v1+0(FP), X0
MOVUPS v2+16(FP), X1
MULPS X1, X0
// also tried ret+32 since I've seen some places do that
MOVUPS X0, toReturn+32(FP)
RET
Run Code Online (Sandbox Code Playgroud)
vec.go
package simd
type Vec4 [4]float32
func (v1 Vec4) Mul(v2 Vec4) Vec4 {
return Vec4{v1[0] * v2[0], v1[1] * v2[1], v1[2] * v2[2], v1[3] * v2[3]}
}
func mul(v1, v2 Vec4) Vec4
Run Code Online (Sandbox Code Playgroud)
simd_test.go
package simd
import (
"testing"
)
func TestMul(t *testing.T) …Run Code Online (Sandbox Code Playgroud) 我有一个包含二进制文件和库的箱子.该库对依赖性非常轻,而二进制文件需要更多,例如,加载文件或做范围并行的事情.
目前,我的Cargo.toml设置如下:
[dependencies.kdtree]
path = "../kdtree"
[dependencies]
rand="0.3.0"
rustc-serialize = "0.3"
csv = {git = "https://github.com/BurntSushi/rust-csv.git"}
crossbeam = "0.2"
num_cpus = "0.2"
[lib]
name = "conformal"
path = "src/lib.rs"
[[bin]]
name = "ucitest"
path = "src/bin/main.rs"
Run Code Online (Sandbox Code Playgroud)
库需要的唯一依赖项是kdtree和rand.但是,即使您只构建库,它似乎仍然构建了仅二进制依赖项.我已经尝试使用features各种花样像[[bin].dependencies]或[ucitest-dependencies](或添加dependencies= []线下[[bin]]),我认为可能使他们只建立二进制,但我不能找到一种方法.
这些不足以使这成为一个问题,但它困扰着我.有没有办法缩小依赖关系,以便它们只为特定的二进制文件构建?
我有两个Vecs对应于一个特征向量列表及其对应的类标签,我想按类标签对它们进行共同排序.
但是,Rust's sort_by在一个切片上运行而不是在特征(或类似)上的泛型函数,并且闭包只获得要比较的元素而不是索引,所以我可以偷偷地破解这种并行的排序.
我考虑过这个解决方案:
let mut both = data.iter().zip(labels.iter()).collect();
both.sort_by( blah blah );
// Now split them back into two vectors
Run Code Online (Sandbox Code Playgroud)
我不希望每次都分配一个全新的矢量,因为数据的大小可能非常大.
当然,我总是可以实现自己的排序,但如果有一种内置的方法可以做到这一点,那就更好了.
注意:这不是这个问题的重复,因为我知道你什么时候会使用单向通道.我一直这样做.我的问题是为什么这个程序是有效的:
func main() {
ch := make(chan<- int)
ch <- 5
fmt.Println("Hello, playground")
}
Run Code Online (Sandbox Code Playgroud)
当然,运行它会造成僵局.如果您使用%T检查类型,则Go确实报告类型ch是仅发送通道.在Go中,你被允许使用make单向通道,但它没有多大意义,因为通过创建一个只有单向通道的通道,你可以确保至少有一个读/写永远不会发生.
一个可能的解释是强制goroutine挂起,但这很容易实现select {}.
我唯一的另一个想法是强迫goroutine只做一些事情n,
ch := make(chan<- int, 50)
// do something 50 times, since then the buffer is full
for {
ch <- doSomething()
}
Run Code Online (Sandbox Code Playgroud)
但是,通过任意数量的不同结构,这更容易,更不用说容易混淆了.
这只是对类型系统的怪癖/疏忽,还是有用于我没想到的这种行为?
我在一个ssh友好的实验室机器上有一个帐户,我存储了很多私人项目,所以我可以从多台计算机访问它们(它允许我只使用我的几个私人Github存储库来处理多个人将要处理的事情).
Rust似乎很有能力通过使用像这样的东西来获取本地和公共数据
[dependencies.foo]
git = "https://github.com/bar/foo"
[dependencies.baz]
path = "/path/to/baz"
Run Code Online (Sandbox Code Playgroud)
但我还没有找到一种方法让它使用ssh git工作(例如git = "git@github.com:bar/foo",或者在我的情况下labmachine:bar/foo).我有无密码/ keygen ssh设置,如果这有帮助.
如果不存在,这不是什么大问题.目前我只是手动克隆存储库和使用path = ../foo,只要我保持我的目录结构相同,并记住pull在我的所有机器上手动所有依赖项.但是,如果我可以设置Cargo来做这件事会让事情变得容易多了,特别是如果我只需要在我的笔记本电脑上快速演示一些东西.
从1.0开始,这个站点在Rust中有六种类型的语法扩展.Decorator,Modifier,MultiModifier,NormalTT,IdentTT,和MacroRulesTT.
不幸的是,它们与这些(和相关编译器扩展)项目的文档的所有链接似乎都已不存在.实际上,即使手动搜索Rust文档中的SyntaxExtension甚至语法模块也不会产生任何结果.它似乎仍然存在于主分支的主要Rust存储库中,所以显然不仅仅是在托儿所的某个地方.
值得注意的是,该页面在某个时刻"很快"(从1.0开始)提到MultiModifier并且Modifier可能合并,但由于文档消失,我无法确认当前的Nightly.
这本书只记录了基本的lints和"程序宏",它们的范围似乎相当有限.
那么,截至目前,还有6种语法扩展类型吗?他们的文档是否在某个新位置保持最新?他们每个人的表现还是和1.0左右一样吗?
我正在尝试根据Option函数的输入切换行为.想法是基于给定Option是否存在来迭代.这是一个最小的,如果愚蠢的例子:
use std::iter;
fn main() {
let x: Option<i64> = None;
// Repeat x 5 times if present, otherwise count from 1 to 5
for i in match x {
None => 1..5,
Some(x) => iter::repeat(x).take(5),
} {
println!("{}", i);
}
}
Run Code Online (Sandbox Code Playgroud)
我收到一个错误:
error[E0308]: match arms have incompatible types
--> src/main.rs:7:14
|
7 | for i in match x {
| ______________^
8 | | None => 1..5,
9 | | Some(x) => iter::repeat(x).take(5),
| | …Run Code Online (Sandbox Code Playgroud) 有时我会遇到一个问题,由于实现细节应该对用户不可见,我需要“销毁” a&mut并在内存中替换它。这通常最终发生在递归方法或递归结构的 IntoIterator 实现中。它通常遵循以下形式:
fn create_something(self);
pub fn do_something(&mut self) {
// What you want to do
*self = self.create_something();
}
Run Code Online (Sandbox Code Playgroud)
我在当前项目中碰巧遇到的一个例子是在我编写的 KD 树中,当我“删除”一个节点时,我没有执行逻辑来重新排列子节点,而是解构我需要删除并重建它的节点从其子树中的值:
// Some recursive checks to identify is this is our node above this
if let Node{point, left, right} = mem::replace(self, Sentinel) {
let points = left.into_iter().chain(right.into_iter()).collect();
(*self) = KDNode::new(points);
Some(point)
} else {
None
}
Run Code Online (Sandbox Code Playgroud)
另一个更深入的例子是这个 KDTree 的 IntoIterator,它必须将一个curr值移出迭代器,测试它,然后替换它:
// temporarily swap self.curr with a dummy value so we can
// move …Run Code Online (Sandbox Code Playgroud) 在Rust中,在编写具有特征的模块时,我倾向于设计问题.我不总是确定我是否想要:
pub trait Foo {
fn foo(&self) -> bool;
fn bar(&self) {
if self.foo() {
// Do something!
} else {
// Do something else!
}
}
}
Run Code Online (Sandbox Code Playgroud)
要么
pub trait Foo {
fn foo(&self) -> bool;
}
pub fn bar<T>(fooer: &T) where T: Foo {
if fooer.foo() {
// Do something!
} else {
// Do something else!
}
}
Run Code Online (Sandbox Code Playgroud)
(当然,真实的例子可能有更复杂的特征或功能签名)
虽然设计问题超出了Stack Overflow的范围,但我并不完全确定我能理解两者之间有意义的,客观的差异,而且我不觉得浏览标准库已经有了很多不足之处.它看起来像生锈一样的标准库更喜欢使用variable.method(),而不是mod::function(&variable)在大多数情况下.然而,这仍然没有真正回答这个问题,因为这只是一个风格指南论证,而不是基于对差异的客观知识.
除了明显的语法差异之外,默认特征方法和模块级参数化函数之间的主要功能差异是什么?我遇到的一个大问题是:默认的特征方法是单形的,以便使用静态调度,还是将它self视为特征对象?
我所看到的唯一区别是,特征的一个impl特性可能会选择覆盖默认的方法实现,希望/可能提供一个实现相同合同的实现,而我保证mod::function实现总是运行完全相同的代码,无论是什么(无论好坏).还有别的事吗?如果涉及相关类型或扩展特征,答案是否会改变?
我现在有点束缚了.我的个人代码依赖于rand,目前没有在Nightly 1.7上编译,但确实可以在Beta 1.6上运行并且稳定.
但是,我的工作还使用了不稳定的功能,例如box语法/模式/原始convert,并且不能(轻松)重构.有没有办法,包括从源代码编译,得到Rust 1.6"好像"它是一个夜间?我在Windows(10)/ MSYS 2上,如果这使任何事情变得复杂,例如构建源代码.
我正在mgo使用MongoDB和Go.我有以下代码:
func Find(collectionName, dbName string, query interface{}) (result []interface{}, err error) {
collection := session.DB(dbName).C(collectionName)
err = collection.Find(query).All(&result)
return result, err
}
func GetTransactionID() (id interface{}, err error) {
query := bson.M{}
transId, err := Find("transactionId", dbName, query)
for key, value := range transId {
fmt.Println("k:", key, "v:", value)
}
}
Run Code Online (Sandbox Code Playgroud)
Output: k:0 v:map [_id:ObjectIdHex("536887c199b6d0510964c35b")transId:A000000000]
我需要从切片中返回的map值中获取_id和transId的值Find.我怎样才能做到这一点?
我有一个像“aaaabbbccccc”这样的字符串。我想在字符串的chars迭代器上创建一个适配器,以生成相同字符的计数。输出(count)需要是连续相同字符的数量。例如:
let s = "aaaabbbccccc"
for count in s.chars().MAGIC() {
println!("{}", count)
}
// prints: 4, 3, 5
Run Code Online (Sandbox Code Playgroud)
更新:这几乎有效:过去不考虑字母:
let s = "aaaabbbcccccdd".to_string();
let mut tt = (s.chars().nth(0).unwrap(), 0);
for a in s.chars().filter_map(|x| {
if x != tt.0 {
tt.0 = x;
let tt_temp = tt.1;
tt.1 = 1;
Some(tt_temp)
} else {
tt.1 += 1;
None
}
}) {
println!("{:?}", a);
}
Run Code Online (Sandbox Code Playgroud) 我正在使用Numpy从.csv文件中加载一堆16x16图像。每行是存储在CMO中的256个灰度值的列表(因此形状为(n,256),其中n是图像数)。这意味着我可以使用pyplot将任何图像显示为:
plot.imshow(np.reshape(images[index], (16,16), order='F'), cmap=cm.Greys_r)
Run Code Online (Sandbox Code Playgroud)
我想用每行一定数量的图像平铺这些图像。我有一个可行的解决方案:
def TileImage(imgs, picturesPerRow=16):
# Convert to a true list of 16x16 images
tmp = np.reshape(imgs, (-1, 16, 16), order='F')
img = ""
for i in range(0, tmp.shape[0], picturesPerRow):
# On the last iteration, we may not have exactly picturesPerRow
# images left so we need to pad
if tmp.shape[0] - i >= picturesPerRow:
mid = np.concatenate(tmp[i:i+picturesPerRow], axis=1)
else:
padding = np.zeros((picturesPerRow - (tmp.shape[0] -i), 16, 16))
mid = np.concatenate(np.concatenate((tmp[i:tmp.shape[0]], padding), axis=0), axis=1)
if img …Run Code Online (Sandbox Code Playgroud)