C++17でモンテカルロを並列化してみた。に触発されて、GNU版で作ってみました
■コンパイル $ g++ test.cc -Wall -march=native -std=c++17 -O3 -fopenmp■ソース #include <parallel/algorithm> //#include <execution> #include <atomic> #include <mutex> #include <iostream> #include <random> #include <array> #include <stdlib.h> int main(int argc, char *argv[]) { static int const NUM = 1000000000; static int threads = 8; static_assert(std::atomic<int>::is_always_lock_free); if (argc >= 2) { threads = atoi(argv[1]); } auto nums = std::vector<int>(threads); for (auto &num : nums) { num = NUM / threads; } __gnu_parallel::_Settings s; s.algorithm_strategy = __gnu_parallel::force_parallel; __gnu_parallel::_Settings::set(s); std::atomic counter = {0}; __gnu_parallel::for_each(nums.begin(), nums.end(), [&counter](int num) { std::random_device rnd; thread_local std::mt19937 mt(rand()); std::uniform_real_distribution<double> score(0.0, 1.0); for (auto &&no = 0; no < num; ++no) { auto &&x = score(mt); auto &&y = score(mt); if ((x * x + y * y) < 1.0) { counter++; } } }); std::cout << "PI = " << 4.0 * counter / NUM << std::endl; }■結果 $ time ./a.out 1 PI = 3.14155 real 0m27.461s user 0m27.469s sys 0m0.001s $ time ./a.out 2 PI = 3.14159 real 0m29.238s user 0m58.008s sys 0m0.016s $ time ./a.out 3 PI = 3.14151 real 0m28.447s user 1m24.458s sys 0m0.000s $ time ./a.out 4 PI = 3.14155 real 0m32.101s user 2m5.238s sys 0m0.020s なぜか延べ時間(user)が増えるだけでreal時間が減りません。。。 そこでソースを修正してみました。 ■ソース修正後 #include <parallel/algorithm> //#include <execution> #include <atomic> #include <mutex> #include <iostream> #include <random> #include <array> #include <stdlib.h> int main(int argc, char *argv[]) { static int const NUM = 1000000000; static int threads = 8; static_assert(std::atomic<int>::is_always_lock_free); if (argc >= 2) { threads = atoi(argv[1]); } auto nums = std::vector<int>(threads); for (auto &num : nums) { num = NUM / threads; } __gnu_parallel::_Settings s; s.algorithm_strategy = __gnu_parallel::force_parallel; __gnu_parallel::_Settings::set(s); std::atomic counter = {0}; __gnu_parallel::for_each(nums.begin(), nums.end(), [&counter](int num) { std::random_device rnd; thread_local std::mt19937 mt(rand()); int _counter = 0; std::uniform_real_distribution<double> score(0.0, 1.0); for (auto &&no = 0; no < num; ++no) { auto &&x = score(mt); auto &&y = score(mt); if ((x * x + y * y) < 1.0) { _counter++; } } counter += _counter; }); std::cout << "PI = " << 4.0 * counter / NUM << std::endl; }■結果 $ time ./a.out 1 PI = 3.14155 real 0m20.263s user 0m20.255s sys 0m0.000s $ time ./a.out 2 PI = 3.14159 real 0m10.117s user 0m20.223s sys 0m0.000s $ time ./a.out 3 PI = 3.14151 real 0m7.409s user 0m22.209s sys 0m0.000s $ time ./a.out 4 PI = 3.14155 real 0m6.129s user 0m24.492s sys 0m0.001score4個分で20秒から6秒にその後、8個に増やしても増えませんでした。。。 なかなかのパフォーマンスなり。 PR |
令和SECCONに参加するのでTSURUGI Linuxを入れてみました。
fluxboxに切り替えて「fbmenugen」を使ったら「Other」に「TSURUGI」メニューが全て入ってカテゴリが分からなくなってしまいました。 仕方がないのでpythonでmateからfluxboxのmenuに変換するプログラムを作成、すっきりしましたとさ。 ■変換用python import sys from xml.dom import minidom from os import path from collections import OrderedDict APP_Directory = None DIR_Directory = None def main(): global APP_Directory global DIR_Directory if len(sys.argv)!=2: print("Using: {} mate.conf".format(sys.argv[0])) return fileName = sys.argv[1] APP_Directory = path.abspath(path.dirname(fileName)+"/../applications") DIR_Directory = path.abspath(path.dirname(fileName)+"/../desktop-directories") print(fileName) with open(fileName, "r", True, "UTF-8") as r: x = "\n".join(r.readlines()) myDom = minidom.parseString(x) recurseDict(myDom, 0, []) def recurseDict(dic, layer, stack): #dic = minidom.parseString("") layer+=1 if sum(1 for x in dic.childNodes if not isinstance(x, minidom.Text)): if dic.nodeName != "Layout": for d in dic.childNodes: if not isinstance(d, minidom.Text): recurseDict(d, layer, stack) else: if dic.nodeName == "Directory": lidx = 0 for lidx in range(len(stack), 0, -1): if layer > stack[lidx-1][0]: break for _ in range(lidx, len(stack)): stack.pop() print("{}[end]".format(" "*(len(stack)*2))) v = readFile(DIR_Directory+"/"+dic.childNodes[0].nodeValue) print("{}[submenu] ({}) <{}>".format(" "*(len(stack)*2), v["Name"], v["Icon"])) stack.append((layer, v)) if dic.nodeName == "Filename": v = readFile(APP_Directory+"/"+dic.childNodes[0].nodeValue) print("{}[exec] ({}) {{{}}} <{}>".format(" "*(len(stack)*2), v["Name"], v["Exec"], v["Icon"])) if layer==1: for _ in range(len(stack)): stack.pop() print("{}[end]".format(" "*(len(stack)*2))) def readFile(fileName): with open(fileName, "r", True, "UTF-8") as r: rec=dict() while True: line = r.readline() if line=="": break line = line[:-1] pos = line.find("=") if pos >=0: key = line[0:pos] if ["Icon", "Name", "Exec"].count(key): rec[key] = line[pos+1:] return rec if __name__ == "__main__": main()■fbmenugenにinclude機能を追加 diff --git a/fbmenugen b/fbmenugen index 84e268b..fa5e784 100755 --- a/fbmenugen +++ b/fbmenugen @@ -401,6 +401,14 @@ ITEM_WITH_ICON ITEM } +sub prepare_include { + my $path= shift() =~ s/\)/\\)/gr; + + return <<"EOF" + [include] ($path) +EOF +} + sub begin_category { $with_icons ? <<"MENU_WITH_ICON" @@ -479,6 +487,9 @@ foreach my $schema (@$SCHEMA) { elsif (exists $schema->{item}) { $generated_menu .= prepare_item(@{$schema->{item}}); } + elsif (exists $schema->{include}) { + $generated_menu .= prepare_include(@{$schema->{include}}); + } elsif (exists $schema->{sep}) { $generated_menu .= "[separator]\n"; } diff --git a/schema.pl b/schema.pl index 18a824a..50ae0dd 100644 --- a/schema.pl +++ b/schema.pl @@ -5,6 +5,7 @@ =for comment item: add an item inside the menu {item => ["command", "label", "icon"]}, + include: add include another file {include => ["path"]}, cat: add a category inside the menu {cat => ["name", "label", "icon"]}, sep: horizontal line separator {sep => undef}, {sep => "label"}, raw: any valid Fluxbox menu entry {raw => q(...)}, |
CUPSのいつもの設定
■/etc/cups/cupsd.conf ...
# Restrict access to the admin pages...
<Location /admin>
Require user @SYSTEM
Order allow,deny
</Location>
...
■cups-pdfのインストール sudo apt install cups-pdf ■/etc/cups/cups-pdf.conf ... ### Key: Out (config) ## CUPS-PDF output directory ## special qualifiers: ## ${HOME} will be expanded to the user's home directory ## ${USER} will be expanded to the user name ## in case it is an NFS export make sure it is exported without ## root_squash! ## on Ubuntu, the cupsd AppArmor profile needs to be updated ## to match the output path as per instructions in LP:147551 ### Default: /var/spool/cups-pdf/${USER} Out${HOME} ... ### Key: GSCall (config) ## command line for calling GhostScript (!!! DO NOT USE NEWLINES !!!) ## MacOSX: for using pstopdf set this to %s %s -o %s %s ### Default: %s -q -dCompatibilityLevel=%s -dNOPAUSE -dBATCH -dSAFER -sDEVICE=pdfwrite -sOutputFile="%s" -dAutoRotatePages=/PageByPage -dAutoFilterColorImages=false -dColorImageFilter=/FlateEncode -dPDFSETTINGS=/prepress -c .setpdfwrite -f %s GSCall /usr/local/bin/cups-pdf-common %s %s "%s" %s ... ■/usr/local/bin/cups-pdf-common #!/bin/bash export MY_GS=$1 export MY_VER=$2 HOME=$(dirname "$3") USER=$(basename ${HOME}) export MY_IN=$4 export MY_OUT=$(basename "$3") execpath=~/bin/cups-pdf if [ -f ${execpath} ] then ${execpath} fi ■~/bin/cups-pdf #!/bin/bash #Ps2PDF ${MY_GS} -q -dCompatibilityLevel=${MY_VER} -dNOPAUSE -dBATCH -dSAFER -sDEVICE=pdfwrite -sOutputFile="${HOME}/PDF/$(date +%Y%m%d_%H%M%S.%N)_${MY_OUT}" -dAutoRotatePages=/PageByPage -dAutoFilterColorImages=false -dColorImageFilter=/FlateEncode -dPDFSETTINGS=/prepress -c .setpdfwrite -f ${MY_IN} |
GRUB2でメニューの表示の仕方
※GRUB_HIDDEN_TIMEOUT_QUIETは関係ありません。 /etc/default/grub GRUB_DEFAULT=0 GRUB_DISABLE_SUBMENU=y GRUB_TIMEOUT_STYLE=menu GRUB_TIMEOUT=3 |
忍者ブログ [PR] |