[PATCH v3] Make fprintf() function to multithread-safe

Peng Haitao penght@cn.fujitsu.com
Tue Jul 31 08:46:00 GMT 2012


Hi, Carlos

On 07/24/2012 10:01 PM, Carlos O'Donell wrote:
>> The test method is OK?
> 
> It is a good start.
> 
> (a) Threading?
> 
> You need two tests.
> 
> You already have the single-thread test case.

The single-thread test result is as follows:
Before the patch, execute the test program with 200 times:
# gcc -o fprintf fprintf_test.c -Wl,-dynamic-linker=/home/pht/sda2/glibc-install/lib/ld-linux-x86-64.so.2 
# perf stat -r 100 -e instructions -- ./fprintf > /dev/null

 Performance counter stats for './fprintf' (100 runs):

     3,837,334,259 instructions              #    0.00  insns per cycle          ( +-  0.00% )

       0.580850804 seconds time elapsed                                          ( +-  0.16% )

# perf stat -r 100 -e instructions -- ./fprintf > /dev/null

 Performance counter stats for './fprintf' (100 runs):

     3,837,347,435 instructions              #    0.00  insns per cycle          ( +-  0.00% )

       0.581234180 seconds time elapsed                                          ( +-  0.19% )


After the patch, execute the test program with 200 times:
# gcc -o fprintf_new fprintf_test.c -Wl,-dynamic-linker=/home/pht/source/glibc-install/lib/ld-linux-x86-64.so.2 
# perf stat -r 100 -e instructions -- ./fprintf_new > /dev/null

 Performance counter stats for './fprintf_new' (100 runs):

     3,853,306,893 instructions              #    0.00  insns per cycle          ( +-  0.00% )

       0.570600865 seconds time elapsed                                          ( +-  0.22% )

# perf stat -r 100 -e instructions -- ./fprintf_new > /dev/null

 Performance counter stats for './fprintf_new' (100 runs):

     3,853,295,107 instructions              #    0.00  insns per cycle          ( +-  0.00% )

       0.568688034 seconds time elapsed                                          ( +-  0.14% )

> 
> You are missing the multi-threaded test case to show the impact of the 
> global lock contention. You should spawn more threads than you have
> CPUs to ensure contention happens sooner, but not so many threads that
> context switching overhead dominates the measurement.
> 

The multi-threaded test result is as follows:
Before the patch, execute the test program with 200 times:
# gcc -o fprintf_mul fprintf_mul_test.c -Wl,-dynamic-linker=/home/pht/sda2/glibc-install/lib/ld-linux-x86-64.so.2 -lpthread
# perf stat -r 100 -e instructions -- ./fprintf_mul > /dev/null

 Performance counter stats for './fprintf_mul' (100 runs):

     3,933,978,985 instructions              #    0.00  insns per cycle          ( +-  0.34% )

       1.652771261 seconds time elapsed                                          ( +-  0.62% )

# perf stat -r 100 -e instructions -- ./fprintf_mul > /dev/null

 Performance counter stats for './fprintf_mul' (100 runs):

     3,954,301,654 instructions              #    0.00  insns per cycle          ( +-  0.35% )

       1.662600499 seconds time elapsed                                          ( +-  0.59% )


After the patch, execute the test program with 200 times:
# gcc -o fprintf_mul_new fprintf_mul_test.c -Wl,-dynamic-linker=/home/pht/source/glibc-install/lib/ld-linux-x86-64.so.2  -lpthread
# perf stat -r 100 -e instructions -- ./fprintf_mul_new > /dev/null

 Performance counter stats for './fprintf_mul_new' (100 runs):

     3,613,283,984 instructions              #    0.00  insns per cycle          ( +-  0.14% )

       1.389559300 seconds time elapsed                                          ( +-  0.22% )

# perf stat -r 100 -e instructions -- ./fprintf_mul_new > /dev/null

 Performance counter stats for './fprintf_mul_new' (100 runs):

     3,615,699,815 instructions              #    0.00  insns per cycle          ( +-  0.15% )

       1.392553792 seconds time elapsed                                          ( +-  0.22% )



# time ./fprintf > /dev/null

real	0m0.589s
user	0m0.584s
sys	0m0.003s
# time ./fprintf_new > /dev/null

real	0m0.572s
user	0m0.567s
sys	0m0.004s
# time ./fprintf_mul > /dev/null

real	0m1.064s
user	0m1.196s
sys	0m0.623s
# time ./fprintf_mul_new > /dev/null

real	0m0.997s
user	0m1.175s
sys	0m0.476s



Test environment:
Kernel: 3.4.6-2.fc17.x86_64
CPU:    Intel(R) Core(TM) i5-2400 CPU @ 3.10GHz
Memory: 8G
OS:     Fedora release 17 (Beefy Miracle)
glibc:  glibc-2.16-ports-merge-90-gbea9b19
patch:  0001-Fix-the-race-between-atexit-and-exit.patch
        0002-Make-fprintf-function-to-multithread-safe.patch

In this test environment, the performance is up after global lock.
I don't understand why:(

The single-thread test program is fprintf_test.c
The multi-thread test program is fprintf_mul_test.c

-- 
Best Regards,
Peng

> They should remain distinct tests.
> 
> (b) Statistics.
> 
> Please run the single-threaded test case hundreds of times.
> 
> Three runs is not sufficient.
> 
> Hundreds of runs will be sufficient to give a high confidence interval
> regardless of the questions we ask later.
> 
> Please run the multi-threaded test case millions of times.
> 
> Why? We are looking to measure the impact of lock contention and if
> the locks aren't contended then it won't measure what we're interested
> in measuring. The number of iterations you need to run is going to
> be inversely proportional to the rate of contention. If you contend
> a lock only once in a thousand acquisitions, then you need to have run
> at least a thousand iterations to measure the impact of the acquisition.
> 
> (c) Document it on the wiki please.
> 
> All performance related patches need their acceptance criteria
> documented on the wiki. It doesn't have to be perfect, but we want
> to capture the history of performance so we can evaluate newer
> patches and methods against the good work you did today.
> 
> Please start documenting here:
> http://sourceware.org/glibc/wiki/benchmarking/results_2_17
> 
> Does all of this make sense?
> 
> Cheers,
> Carlos.
> 

-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-Fix-the-race-between-atexit-and-exit.patch
Type: text/x-patch
Size: 8714 bytes
Desc: not available
URL: <http://sourceware.org/pipermail/libc-alpha/attachments/20120731/c8c8dcf4/attachment.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0002-Make-fprintf-function-to-multithread-safe.patch
Type: text/x-patch
Size: 4820 bytes
Desc: not available
URL: <http://sourceware.org/pipermail/libc-alpha/attachments/20120731/c8c8dcf4/attachment-0001.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: fprintf_mul_test.c
Type: text/x-csrc
Size: 1702 bytes
Desc: not available
URL: <http://sourceware.org/pipermail/libc-alpha/attachments/20120731/c8c8dcf4/attachment-0002.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: fprintf_test.c
Type: text/x-csrc
Size: 1246 bytes
Desc: not available
URL: <http://sourceware.org/pipermail/libc-alpha/attachments/20120731/c8c8dcf4/attachment-0003.bin>


More information about the Libc-alpha mailing list