OpenMPを使った並列プログラムを試していて,いろいろ疑問に思ったことなのだが,場合によっては全然性能が上がらないことがある.
簡単なプログラムを作って,その動作をか確かめてみたい:
printf("# of threads: %d\n", nthread); printf("# of processors: %d\n", omp_get_num_procs()); omp_set_num_threads(nthread); double st = omp_get_wtime(); #pragma omp parallel { #pragma omp for for (int i=0; i<SIZE; i++) { z[i] = x[i] + y[i]; } } double en = omp_get_wtime(); std::cout << "finished\n";
PARAM_SIZE = 3000000 run: build ./main 1 100 $(PARAM_SIZE) ./main 2 100 $(PARAM_SIZE) ./main 4 100 $(PARAM_SIZE) ./main 8 100 $(PARAM_SIZE) build: g++ -fopenmp main.cc -o main
普通にやるとコア数を増やすと一応スケールしているように見える.
Time : 3.54631 Time : 1.90455 Time : 1.39926 Time : 1.61617
でも,-O3
を入れるとスケーラビリティが落ちる:
g++ -O3 -fopenmp main.cc -o main
Time : 1.59019 Time : 1.2655 Time : 1.26703 Time : 1.4477
これ,良く分からないのだが,たぶんOpenMPで並列化したときにオーバヘッドが大きすぎるのではないのか. ある程度並列度があって,スレッドの処理が負荷があるとスケールするのかもしれないけど,各処理が小さすぎるとオーバヘッドのほうが大きいのかもしれない.
<main._omp_fn.0>:
とか,本処理の前のオーバヘッドが非常に大きく見える.
112aa: 711d add sp,sp,-96 112ac: ec86 sd ra,88(sp) 112ae: e8a2 sd s0,80(sp) 112b0: e4a6 sd s1,72(sp) 112b2: e0ca sd s2,64(sp) 112b4: 1080 add s0,sp,96 112b6: faa43423 sd a0,-88(s0) 112ba: fa843783 ld a5,-88(s0) 112be: 6b9c ld a5,16(a5) 112c0: fcf43823 sd a5,-48(s0) 112c4: fa843783 ld a5,-88(s0) 112c8: 679c ld a5,8(a5) 112ca: fcf43423 sd a5,-56(s0) 112ce: fa843783 ld a5,-88(s0) 112d2: 639c ld a5,0(a5) 112d4: fcf43023 sd a5,-64(s0) 112d8: fa843783 ld a5,-88(s0) 112dc: 4f9c lw a5,24(a5) 112de: faf42e23 sw a5,-68(s0) 112e2: fbc42903 lw s2,-68(s0) 112e6: c0bff0ef jal 10ef0 <omp_get_num_threads@plt> 112ea: 87aa mv a5,a0 112ec: 84be mv s1,a5 112ee: bb3ff0ef jal 10ea0 <omp_get_thread_num@plt> 112f2: 87aa mv a5,a0 112f4: 86be mv a3,a5 112f6: 029947bb divw a5,s2,s1 112fa: 2781 sext.w a5,a5 112fc: 874a mv a4,s2 112fe: 0297673b remw a4,a4,s1 11302: 2701 sext.w a4,a4 11304: 85b6 mv a1,a3 11306: 863a mv a2,a4 11308: 06c5c663 blt a1,a2,11374 <main._omp_fn.0+0xca> 1130c: 02d786bb mulw a3,a5,a3 11310: 2681 sext.w a3,a3 11312: 9f35 addw a4,a4,a3 11314: 2701 sext.w a4,a4 11316: 9fb9 addw a5,a5,a4 11318: 0007869b sext.w a3,a5 1131c: 863a mv a2,a4 1131e: 87b6 mv a5,a3 11320: 04f65e63 bge a2,a5,1137c <main._omp_fn.0+0xd2> 11324: fce42e23 sw a4,-36(s0) 11328: fdc42783 lw a5,-36(s0) 1132c: 078a sll a5,a5,0x2 1132e: fc043703 ld a4,-64(s0) 11332: 97ba add a5,a5,a4 11334: 0007a707 flw fa4,0(a5) 11338: fdc42783 lw a5,-36(s0) 1133c: 078a sll a5,a5,0x2 1133e: fc843703 ld a4,-56(s0) 11342: 97ba add a5,a5,a4 11344: 0007a787 flw fa5,0(a5) 11348: fdc42783 lw a5,-36(s0) 1134c: 078a sll a5,a5,0x2 1134e: fd043703 ld a4,-48(s0) 11352: 97ba add a5,a5,a4 11354: 00f777d3 fadd.s fa5,fa4,fa5 // 本体の処理はココ 11358: 00f7a027 fsw fa5,0(a5) 1135c: fdc42783 lw a5,-36(s0) 11360: 2785 addw a5,a5,1 11362: fcf42e23 sw a5,-36(s0) 11366: fdc42783 lw a5,-36(s0) 1136a: 2781 sext.w a5,a5 1136c: 8736 mv a4,a3 1136e: fae7cde3 blt a5,a4,11328 <main._omp_fn.0+0x7e> 11372: a029 j 1137c <main._omp_fn.0+0xd2> 11374: 4701 li a4,0 11376: 2785 addw a5,a5,1 11378: 2781 sext.w a5,a5 1137a: bf49 j 1130c <main._omp_fn.0+0x62> 1137c: 0001 nop 1137e: 60e6 ld ra,88(sp) 11380: 6446 ld s0,80(sp) 11382: 64a6 ld s1,72(sp) 11384: 6906 ld s2,64(sp) 11386: 6125 add sp,sp,96 11388: 8082 ret