我在C中实现了Barnes-Hut重力算法如下:
阶段2是最昂贵的阶段,因此通过划分星组来并行实施.例如,有1000颗星和2个线程,我有一个线程处理前500颗星,第二个线程处理第二个500颗.
在实践中,这是有效的:与非线程版本相比,它在双核机器上使用两个线程将计算速度提高了大约30%.此外,它产生与原始非线程版本相同的数值结果.
我担心的是两个线程同时访问相同的资源(即树).我没有向线程工作者添加任何同步,因此他们可能会尝试在某个时刻从同一位置读取.虽然访问树是严格只读的,但我并不是100%确定它是安全的.它在我测试它时起作用,但我知道这不能保证正确性!
问题
更新好奇的基准测试结果:
机器:Intel Atom CPU N270 @ 1.60GHz,cpu MHz 800,高速缓存大小512 KB
Threads real user sys
0 69.056 67.324 1.720
1 76.821 66.268 5.296
2 50.272 63.608 10.585
3 55.510 55.907 13.169
4 49.789 43.291 29.838
5 54.245 41.423 31.094
Run Code Online (Sandbox Code Playgroud)
0表示根本没有线程; 1及以上意味着产生许多工作线程和主线程等待它们.我不希望超过2个线程的任何改进,因为它完全受CPU限制,而且有多少个核心.有趣的是,奇数个线程比偶数更差.
看着sys它显然是制作线程的成本.目前它正在为每个帧创建线程(因此N*1000线程创建).这很容易编程(今天早上我在火车上的15分钟).我需要考虑一下如何重用线程......
更新#2我使用了一个线程池,与两个障碍同步.与每帧重新创建线程相比,这没有明显的性能优势.
我正在尝试编写一个move/3处理几种术语的谓词,每种术语都在一个单独的文件中定义.我正在尝试使用模块,因为这些文件包含应该适当命名的其他谓词.
所以,我创建了一个cat.prolog包含内容的模块:
:- module(cat, [move/3]).
:- multifile(move/3).
move(cat(C), P, cat(C2)) :-
...
Run Code Online (Sandbox Code Playgroud)
同样的dog.prolog.
并main.prolog与:
:- use_module(['cat.prolog'], [move/3]).
:- use_module(['dog.prolog'], [move/3]).
(various predicates that use move/3 and expecting the clauses from all imported modules to be applicable.)
Run Code Online (Sandbox Code Playgroud)
试图在SWI-Prolog中运行它:
?- ['main.prolog'].
% cat.prolog compiled into cat 0.00 sec, 4,800 bytes
ERROR: Cannot import dog:move/3 into module user: already imported from cat
Warning: /home/edmund/main.prolog:2:
Goal (directive) failed: user:use_module([dog.prolog],[move/3])
% main.prolog compiled 0.00 sec, 10,176 bytes …Run Code Online (Sandbox Code Playgroud) 我一直在努力找到一个简明扼要的措辞,所以请继续阅读详细信息和示例......
我正在为Parsec编写一些帮助操作符,从以下开始:
(<@) :: GenParser tok st a -> (a -> b) -> GenParser tok st b
p <@ f = do {
x <- p ;
return (f x)
}
(<>) :: GenParser tok st a -> GenParser tok st b -> GenParser tok st (a, b)
p <> q = do {
x <- p ;
y <- q ;
return (x, y)
}
Run Code Online (Sandbox Code Playgroud)
这些工作如下:
parseTest ((many upper) <@ length) "HELLO"
5
parseTest (many upper) …Run Code Online (Sandbox Code Playgroud) 在使用make和的项目中bison,我很难指定编译的语法grammar.tab.c依赖于语法输入grammar.y,每个目标文件依赖于相应的源文件(包括grammar.tab.o),并且可执行文件依赖于所有目标文件.
问题是make当grammar.tab.c尚不存在时运行意味着没有尝试构建它,并且当构建可执行文件时,该yyparse函数丢失.
我Makefile是:
CFLAGS = -g -Wall
YACC = bison -d -r all
OBJ=$(patsubst %.c, %.o, $(wildcard *.c))
HEADERS=grammar.tab.h hex.h compiler.h types.h
all: grammar.tab.h c
clean:
rm -f $(OBJ) *.tab.c *.tab.h c c.exe *.output
c: $(OBJ)
$(CC) -o $@ $(OBJ) $(CFLAGS)
grammar.tab.c: grammar.y
$(YACC) grammar.y
grammar.tab.h: grammar.y
$(YACC) grammar.y
%.o: %.c $(HEADERS)
$(CC) -c $< $(CFLAGS)
Run Code Online (Sandbox Code Playgroud)
如果我改变它:
OBJ=$(patsubst %.c, %.o, $(wildcard *.c)) grammar.tab.o
Run Code Online (Sandbox Code Playgroud)
然后它将构建已编译的语法(如果它尚不存在).但是如果它已经存在,那么在构建可执行文件时,会出现 …
我有一个问题,即postgres有序的结果不是一致的.我按多个字段排序:ORDER BY categories.position ASC,photos.display_priority
我注意到这一点,因为当您浏览网站时,结果是分页的.我发现了一个从第1页到第2页的情况,在第2页的顶部,我看到了第1页底部附近的照片.
这是我的第1页查询:
SELECT "photos".*
FROM "photos"
INNER JOIN "categories" ON "categories"."id" = "photos"."category_id"
WHERE "photos"."category_id" IN (221, 633, 377, 216, 634)
AND (photos.caption IS NOT NULL
AND photos.category_id IS NOT NULL
AND photos.rights IS NOT NULL
AND photos.deleted IS NULL)
ORDER BY categories.position ASC, photos.display_priority DESC
LIMIT 25 OFFSET 0;
Run Code Online (Sandbox Code Playgroud)
我的第2页查询:
SELECT "photos".*
FROM "photos"
INNER JOIN "categories" ON "categories"."id" = "photos"."category_id"
WHERE "photos"."category_id" IN (221, 633, 377, 216, 634)
AND (photos.caption IS NOT NULL
AND …Run Code Online (Sandbox Code Playgroud) bison ×1
c ×1
compilation ×1
haskell ×1
makefile ×1
module ×1
postgresql ×1
prolog ×1
pthreads ×1
swi-prolog ×1