我知道关于 Julia 中多线程性能的问题已经被问过(例如这里),但它们涉及相当复杂的代码,其中可能有很多东西在起作用。
在这里,我使用 Julia v1.5.3 在多个线程上运行一个非常简单的循环,与使用例如 Chapel 运行相同的循环相比,加速似乎并没有很好地扩展。
我想知道我做错了什么,以及如何更有效地在 Julia 中运行多线程。
using BenchmarkTools
function slow(n::Int, digits::String)
total = 0.0
for i in 1:n
if !occursin(digits, string(i))
total += 1.0 / i
end
end
println("total = ", total)
end
@btime slow(Int64(1e8), "9")
Run Code Online (Sandbox Code Playgroud)
时间:8.034s
Threads.@threads4 个线程上的共享内存并行性using BenchmarkTools
using Base.Threads
function slow(n::Int, digits::String)
total = Atomic{Float64}(0)
@threads for i in 1:n
if !occursin(digits, string(i))
atomic_add!(total, 1.0 / i)
end
end
println("total = ", total)
end
@btime slow(Int64(1e8), …Run Code Online (Sandbox Code Playgroud) 我查看writef()了任何bool说明书的文档,似乎没有.
在Chapel计划中,我有:......
config const verify = false;
/* that works but I want to use writef() to also print a bunch of other stuff*/
writeln("verify = " + verify);
writef("verify = %<what-specifier-goes-here>\n", verify);
Run Code Online (Sandbox Code Playgroud)
这最后一个声明正常.
// I guess I could do:
writef( "verify = %s\n",if verify then "true" else "false");
Run Code Online (Sandbox Code Playgroud) 我正在尝试返回对数组切片的引用,但是我得到了以下编译时错误(其中有问题的行在 slice
test.chpl:9:错误:ref返回非法表达式
返回完整数组工作正常,就像在主程序中引用切片一样.
有没有正确的方法将ref返回到切片?提前致谢!
record R {
var A : [0.. #10] int;
proc full() ref {
return A;
}
proc slice() ref {
return A[0.. #5];
}
}
var r : R;
ref x1 = r.full();
ref x2 = r.slice();
ref x3 = x1[0.. #5];
Run Code Online (Sandbox Code Playgroud)
只是为了完整性:
chpl版本1.16.0预发布(2659cc6)
假设我正在生成元组,我想在它们到来时将它们连接起来.我该怎么做呢?以下是元素添加:
如果ts = ("foo", "cat"),t = ("bar", "dog")
ts += t给ts = ("foobar", "catdog"),
但我真正想要的是ts = (("foo","cat"),("bar","dog")).
所以我想第一个问题是"Chapel是否支持元组连接?",然后"它是否有二元运算符/函数?",然后"如果没有,这是一个很好的方法吗?",最后"make如果你懂得更好的生活方式,我的生活会更轻松".
请按顺序解决问题.
我很感激帮助!!
在过去一年左右的时间里,我一直在尝试Chapel.我过去曾简单地使用过C和C++,但我最近的经验是使用Python,Ruby和Erlang等动态语言.
在接触到Erlang及其功能条款后,我很高兴能够找到Chapel中的子句.但是,我在使用它时遇到了障碍.在Y分钟内学习Chapel包含以下代码,演示如何使用where子句:
proc whereProc(param N : int): void
where (N > 0) {
writeln("N is greater than 0");
}
proc whereProc(param N : int): void
where (N < 0) {
writeln("N is less than 0");
}
whereProc(10);
whereProc(-1);
Run Code Online (Sandbox Code Playgroud)
这会为两个标量值10和-1中的每一个生成预期输出.但是,我试图编写迭代范围或数组的类似程序.我甚至尝试过递归.在所有情况下,我得到基本相同的错误:
whereproc2.chpl:12: error: unresolved call 'whereProc(int(64))'
whereproc2.chpl:1: note: candidates are: whereProc(param N: int)
whereproc2.chpl:6: note: whereProc(param N: int)
Run Code Online (Sandbox Code Playgroud)
产生此特定错误的代码是:
proc whereProc(param N : int): void
where (N > 0) {
writeln("N is greater than 0");
}
proc whereProc(param N : int): void …Run Code Online (Sandbox Code Playgroud) Chapel域有两组方法
domain.low, domain.high
Run Code Online (Sandbox Code Playgroud)
和
domain.first, domain.last
Run Code Online (Sandbox Code Playgroud)
什么是这些返回不同结果的各种情况(即什么时候domain.first != domain.low和domain.last != domain.high?
我想在Chapel中尝试类和多态,所以我试着让以下示例代码工作:
module SomeAnimals {
class Animal {
}
class Bird: Animal {
}
class Fish: Animal {
}
proc Bird.fly() {
writeln("Flying ...!");
}
proc Fish.swim() {
writeln("Swimming ...!");
}
} // module SomeAnimals
proc main() {
use SomeAnimals;
var anim: Animal;
anim = new Fish();
select (anim.type) {
when Fish do anim.swim();
}
delete anim;
anim = new Bird();
select (anim.type) {
when Bird do anim.fly();
}
delete anim;
} // proc main
Run Code Online (Sandbox Code Playgroud)
这个编译,但运行它,它只是退出而不产生任何打印输出.显然,由于某些原因,对select语句中包含的anim.swim()和anim.fly()方法的调用不会被执行.在不使用这些select语句来检查多态变量"anim"的实际类型的情况下,代码当然不会编译.
上面的例子实际上是一个使用Fortran的"选择类型"语句的Fortran 2008代码的相当直译.Chapel是否提供了类似的陈述,或者为了在Chapel工作,这个例子是否必须以完全不同的方式编码?我在Chapel文档中找不到任何相关内容.
我正在尝试查看是否可以使用Chapel编写用于基于Python的气候模型的并行代码:https : //github.com/CliMT/climt
我没有使用Chapel的经验,但是对于我的用例而言,这似乎很有希望。我对如何将Chapel代码集成到当前工作流程中有一些疑问:
我知道您可以构建可导入.so文件,但是在生成Cython文件时可以停止编译吗?然后,我可以将其包含在发行版中,并使用标准setuptools在Travis上编译我的项目。
我可以将numpy数组传递给用Chapel编写的Python扩展吗?
如果对2的答案为是,并且我的计算在数组的一个维度上尴尬地平行,那么是否有一种优雅的方式在Chapel中表达这种并列现象?
如果我编写可在多个节点上使用的Chapel代码并将其编译为Python扩展,如何运行它?我可以使用mpirun python my_code.py某种命令吗?
我一直在用小程序学习Chapel,他们工作得很好.但随着程序变得越来越长,编译时间也变得越来越长.所以我找到了逐个编译多个文件的方法,但还没有成功.通过搜索互联网,我找到了这个和这个页面,后者说
所有这些增量编译功能都在Chapel编译器中使用新的--incremental标志启用,该标志将在Chapel 1.14.0版本中提供.
虽然我的计算机上的Chapel编译器接受此选项,但在编译仅包含过程的文件(即没有main())时,它似乎不会生成任何*.o(或*.a?).这是因为上述项目是实验性的......?在这种情况下,我们可以期望这个功能被包含在Chapel的某个未来版本中吗?
(或者,上面的"增量编译"这个词不是我对GCC这样的通常编译器的预期吗?)
我的环境:在Mac OSX 10.11.6上通过自制软件安装Chapel-1.14.0.
与其他语言不同,Chapel中似乎没有allocate或new语法在堆上分配数组,而是使用通常的"声明"类语法.例如,在下面的代码中,我"声明"了两个数组,A并B在一个基于正式(虚拟)参数的函数中:
proc test( n, D )
{
var A: [1..n] real; // local array
var B: [D] real; // local array
writeln( "A.domain = ", A.domain );
writeln( "B.domain = ", B.domain );
}
test( 3, {2..5} ); // request small arrays
test( 10**7, {-10**7..10**7} ); // request large arrays
Run Code Online (Sandbox Code Playgroud)
这给出了以下结果:
A.domain = {1..3}
B.domain = {2..5}
A.domain = {1..10000000}
B.domain = {-10000000..10000000}
Run Code Online (Sandbox Code Playgroud)
因为没有堆栈溢出(尽管大小很大B),可以假设上面的语法总是在堆上分配A并且B不管它们的大小如何?
此外,域变量的赋值(或重新赋值)似乎扮演了数组的分配(或重新分配)的角色.例如,以下代码按预期工作.在这种情况下,分配是否总是在堆上发生(再次)?
var …Run Code Online (Sandbox Code Playgroud)