我正在研究并行编程并在排序算法上对其进行测试。
我发现最简单的方法是使用 OpenMP,因为它提供了一种实现线程的简单方法。
我做了一个研究,发现其他人已经这样做了,然后我尝试了一些代码。但是,当我在 Linux 上使用 perf stat -r 10 -d 测试它时,我得到的时间比序列化代码更糟糕(在某些情况下,它是时间的两倍)。
我尝试在数组中使用不同数量的元素,我使用的最大值是 1.000.000 个数字,如果我使用更多,我会收到错误。
void merge(int aux[], int left, int middle, int right){
int temp[middle-left+1], temp2[right-middle];
for(int i=0; i<(middle-left+1); i++){
temp[i]=aux[left+i];
}
for(int i=0; i<(right-middle); i++){
temp2[i]=aux[middle+1+i];
}
int i=0, j=0, k=left;
while(i<(middle-left+1) && j<(right-middle))
{
if(temp[i]<temp2[j]){
aux[k++]=temp[i++];
}
else{
aux[k++]=temp2[j++];
}
}
while(i<(middle-left+1)){
aux[k++]=temp[i++];
}
while(j<(right-middle)){
aux[k++]=temp2[j++];
}
}
void mergeSort (int aux[], int left, int right){
if (left < right){
int middle = (left + right)/2;
omp_set_num_threads(2);
#pragma omp parallel
{
#pragma omp sections
{
#pragma omp section
mergeSort(aux,left,middle); //call 1
#pragma omp section
mergeSort(aux,middle+1,right); //call 2
}
}
merge(aux,left,middle,right);
}
}
int main(){
generate_list(Vet, n);
mergeSort(Vet, 0, n-1);
return(0);
}
以下是我收到的结果:
OpenMP 代码:
./mergeomp 的性能计数器统计(10 次运行):
12,489169 task-clock (msec) # 0,717 CPUs utilized ( +- 3,58% )
8 context-switches # 0,681 K/sec ( +- 6,62% )
0 cpu-migrations # 0,000 K/sec
167 page-faults # 0,013 M/sec ( +- 0,79% )
<not supported> cycles
<not supported> instructions
<not supported> branches
<not supported> branch-misses
<not supported> L1-dcache-loads
<not supported> L1-dcache-load-misses
<not supported> LLC-loads
<not supported> LLC-load-misses
0,01743 +- 0,00211 seconds time elapsed ( +- 12,10% )
序列化方式(简单代码):
./mergesort 的性能计数器统计(10 次运行):
3,757053 task-clock (msec) # 0,449 CPUs utilized ( +- 0,72% )
1 context-switches # 0,293 K/sec ( +- 16,32% )
0 cpu-migrations # 0,000 K/sec
139 page-faults # 0,037 M/sec ( +- 0,34% )
<not supported> cycles
<not supported> instructions
<not supported> branches
<not supported> branch-misses
<not supported> L1-dcache-loads
<not supported> L1-dcache-load-misses
<not supported> LLC-loads
<not supported> LLC-load-misses
0,008375 +- 0,000276 seconds time elapsed ( +- 3,29% )
我做错了什么吗?我正在用 -fopenmp 标志编译它,但不知道合并排序是否不适合并行化,或者我的 linux 虚拟机(我在 VM Virtual Box 上运行 Ubuntu机器,我的 PC 有一个 Core I7 处理器)配置不佳。
最佳答案
感谢大家帮助我解决了这个问题。
首先我没有在我的虚拟机上设置多核。
然后,我更改了 task 的 sections 构造。
我还在数组中使用了更多的元素(200 万)。
最后我添加了一个过滤器以在数组小于“n”个元素时停止使用并行性:
void mergeSortSerial(int aux[], int left, int right){
if (left < right){
int middle = (left + right)/2;
mergeSortSerial(aux,left,middle); //call 1
mergeSortSerial(aux,middle+1,right); //call 2
merge(aux,left,middle,right);
}
}
void mergeSort (int aux[], int left, int right){
if (left < right){
if ((right-left) > 1000){
int middle = (left + right)/2;
#pragma omp task firstprivate (aux, left, middle)
mergeSort(aux,left,middle); //call 1
#pragma omp task firstprivate (aux, middle, right)
mergeSort(aux,middle+1,right); //call 2
#pragma omp taskwait
merge(aux,left,middle,right);
} else{mergeSortSerial(aux, left, right);}
}
}
我发现 1.000.000 是“n”的最佳数字,我的算法比顺序算法快 2 倍。
关于c++ - 我的归并排序算法使用 OpenMP 时速度较慢,我怎样才能让它比序列化形式更快?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56060548/
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
我是一个Rails初学者,但我想从我的RailsView(html.haml文件)中查看Ruby变量的内容。我试图在ruby中打印出变量(认为它会在终端中出现),但没有得到任何结果。有什么建议吗?我知道Rails调试器,但更喜欢使用inspect来打印我的变量。 最佳答案 您可以在View中使用puts方法将信息输出到服务器控制台。您应该能够在View中的任何位置使用Haml执行以下操作:-puts@my_variable.inspect 关于ruby-on-rails-如何在我的R
我喜欢使用Textile或Markdown为我的项目编写自述文件,但是当我生成RDoc时,自述文件被解释为RDoc并且看起来非常糟糕。有没有办法让RDoc通过RedCloth或BlueCloth而不是它自己的格式化程序运行文件?它可以配置为自动检测文件后缀的格式吗?(例如README.textile通过RedCloth运行,但README.mdown通过BlueCloth运行) 最佳答案 使用YARD直接代替RDoc将允许您包含Textile或Markdown文件,只要它们的文件后缀是合理的。我经常使用类似于以下Rake任务的东西:
rails中是否有任何规定允许站点的所有AJAXPOST请求在没有authenticity_token的情况下通过?我有一个调用Controller方法的JqueryPOSTajax调用,但我没有在其中放置任何真实性代码,但调用成功。我的ApplicationController确实有'request_forgery_protection'并且我已经改变了config.action_controller.consider_all_requests_local在我的environments/development.rb中为false我还搜索了我的代码以确保我没有重载ajaxSend来发送
我只想对我一直在思考的这个问题有其他意见,例如我有classuser_controller和classuserclassUserattr_accessor:name,:usernameendclassUserController//dosomethingaboutanythingaboutusersend问题是我的User类中是否应该有逻辑user=User.newuser.do_something(user1)oritshouldbeuser_controller=UserController.newuser_controller.do_something(user1,user2)我
如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:
我正在开发我的第一个Rubygem,并捆绑了cucumber、rspec和shoulda-matches进行测试。当我运行rspec时,出现以下错误:/app/my_gem/spec/spec_helper.rb:6:in`':undefinedmethod`configure'forShoulda::Matchers:Module(NoMethodError)这是我的gem规范:#my_gem.gemspec...Gem::Specification.newdo|spec|......spec.add_development_dependency"activemodel"spec.a
我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我
我正在使用Heroku(heroku.com)来部署我的Rails应用程序,并且正在构建一个iPhone客户端来与之交互。我的目的是将手机的唯一设备标识符作为HTTPheader传递给应用程序以进行身份验证。当我在本地测试时,我的header通过得很好,但在Heroku上它似乎去掉了我的自定义header。我用ruby脚本验证:url=URI.parse('http://#{myapp}.heroku.com/')#url=URI.parse('http://localhost:3000/')req=Net::HTTP::Post.new(url.path)#boguspara
require"socket"server="irc.rizon.net"port="6667"nick="RubyIRCBot"channel="#0x40"s=TCPSocket.open(server,port)s.print("USERTesting",0)s.print("NICK#{nick}",0)s.print("JOIN#{channel}",0)这个IRC机器人没有连接到IRC服务器,我做错了什么? 最佳答案 失败并显示此消息::irc.shakeababy.net461*USER:Notenoughparame