{"action":"opened","issue":{"url":"https://api.github.com/repos/Qthreads/qthreads/issues/48","repository_url":"https://api.github.com/repos/Qthreads/qthreads","labels_url":"https://api.github.com/repos/Qthreads/qthreads/issues/48/labels{/name}","comments_url":"https://api.github.com/repos/Qthreads/qthreads/issues/48/comments","events_url":"https://api.github.com/repos/Qthreads/qthreads/issues/48/events","html_url":"https://github.com/Qthreads/qthreads/issues/48","id":193167729,"number":48,"title":"Improve performance of \"thread-ring\" benchmark","user":{"login":"ronawho","id":1588337,"avatar_url":"https://avatars.githubusercontent.com/u/1588337?v=3","gravatar_id":"","url":"https://api.github.com/users/ronawho","html_url":"https://github.com/ronawho","followers_url":"https://api.github.com/users/ronawho/followers","following_url":"https://api.github.com/users/ronawho/following{/other_user}","gists_url":"https://api.github.com/users/ronawho/gists{/gist_id}","starred_url":"https://api.github.com/users/ronawho/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ronawho/subscriptions","organizations_url":"https://api.github.com/users/ronawho/orgs","repos_url":"https://api.github.com/users/ronawho/repos","events_url":"https://api.github.com/users/ronawho/events{/privacy}","received_events_url":"https://api.github.com/users/ronawho/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":0,"created_at":"2016-12-02T17:06:13Z","updated_at":"2016-12-02T17:06:13Z","closed_at":null,"body":"[thread-ring](http://benchmarksgame.alioth.debian.org/u64q/threadring-description.html#threadring) is one of the Computer Language Benchmarks Game (CLBG) codes.\r\n\r\nHaving Chapel sync vars map down to qthreads aligned_t sync vars (https://github.com/Qthreads/qthreads/issues/22, https://github.com/chapel-lang/chapel/pull/4489) dramatically improved performance of thread-ring for us. It resulted in a [6x speedup](http://chapel.sourceforge.net/perf/chapcs/?startdate=2016/09/07&enddate=2016/09/17&graphs=threadringshootoutbenchmarkn50000000) and put us in 4th place for the [actual CLBG competition](http://benchmarksgame.alioth.debian.org/u64q/performance.php?test=threadring)\r\n\r\nThere's Haskell, Go, and F# versions that are beating us, and I'm curious what it would take to get closer to them. Thread-ring is a \"parallel\" application in the sense that it creates a lot of threads/tasks, but only one task actually executes at a time so some of the versions that are beating us do things like limit the runtime to only use one real thread. I wonder if there's a better way to implement thread-ring over qtheads or maybe scheduler/FEB optimizations that would get us better performance. \r\n\r\nHere's a native qthreads version that's based off the Chapel version that we submitted\r\n\r\n```C\r\n#include <stdio.h>\r\n#include <stdlib.h>\r\n#include <assert.h>\r\n#include \"qthread/qthread.h\"\r\n#include <qthread/qloop.h>\r\n\r\n\r\n// native qthreads version of thread-ring, based on Chapel's release version\r\n//   https://github.com/chapel-lang/chapel/blob/master/test/release/examples/benchmarks/shootout/threadring.chpl\r\n\r\n//static int n = 1000, ntasks = 503;\r\nstatic int n = 50000000, ntasks = 503;\r\nstatic aligned_t *mailbox;\r\n\r\nstatic void passTokens(size_t start, size_t stop, void* arg) {\r\n  uint64_t id = start;\r\n\r\n  uint64_t numPasses = 0;\r\n  do {\r\n    qthread_readFE(&numPasses, &mailbox[id]);\r\n    qthread_writeEF_const(&mailbox[(id+1)%ntasks], numPasses+1);\r\n    if (numPasses == n) {\r\n      printf(\"%ld\\n\", (long)id+1);\r\n    }\r\n  } while (numPasses < n);\r\n}\r\n\r\nstatic void init() {\r\n  assert(qthread_initialize() == 0);\r\n  printf(\"%i threads...\\n\", qthread_num_workers());\r\n\r\n  // init array of syncvars (code grabbed from stress/feb_stream.c)\r\n  mailbox = malloc(ntasks * sizeof(aligned_t));\r\n  for (int i=0; i<ntasks; i++) {\r\n    mailbox[i] = 0;\r\n    qthread_empty(&mailbox[i]);\r\n  }\r\n}\r\n\r\nint main(int argc, char **argv) {\r\n  init();\r\n\r\n  qthread_writeEF_const(&mailbox[0], 0);\r\n  qt_loop_simple(0, ntasks, passTokens, NULL);\r\n\r\n  return 0;\r\n}\r\n```\r\n\r\n\r\nIt runs a second or two faster than the chapel version, but it's pretty similar otherwise.\r\n\r\nWe're really happy with the performance we're getting now, so this is a really low priority and it wouldn't bother me if this never got worked on. When I first started looking at mapping down to native qthread sync vars I had a lot of fun playing with different implementation so I figured this could be an interesting/fun side project or something to work on in the background that would still benefit us. Plus, I'd imagine improvements to it would improve the performance of FEB operations in general. "}}
{"actor":{"display_login":"ronawho"}}