Merge commit 'upstream/20081031+intermediate-20081120' into dfsg_clean
[ltp-debian.git] / scratch / hackbench.c
blobc0d713cc8c245ce03f28cbc7b0d6403e81c7a216
1 From linux-kernel-owner@vger.kernel.org Tue Dec 11 01:11:36 2001
2 Received: from sgi.com (sgi.engr.sgi.com [192.26.80.37]) by tulip-e185.americas.sgi.com (980427.SGI.8.8.8/SGI-server-1.7) with ESMTP id BAA82859; Tue, 11 Dec 2001 01:11:36 -0600 (CST)
3 Received: from vger.kernel.org ([199.183.24.194])
4 by sgi.com (980327.SGI.8.8.8-aspam/980304.SGI-aspam:
5 SGI does not authorize the use of its proprietary
6 systems or networks for unsolicited or bulk email
7 from the Internet.)
8 via ESMTP id XAA08571; Mon, 10 Dec 2001 23:11:32 -0800 (PST)
9 mail_from (linux-kernel-owner@vger.kernel.org)
10 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand
11 id <S284902AbRLKHHQ>; Tue, 11 Dec 2001 02:07:16 -0500
12 Received: (majordomo@vger.kernel.org) by vger.kernel.org
13 id <S284914AbRLKHG5>; Tue, 11 Dec 2001 02:06:57 -0500
14 Received: from [202.135.142.194] ([202.135.142.194]:24588 "EHLO
15 wagner.rustcorp.com.au") by vger.kernel.org with ESMTP
16 id <S284913AbRLKHGr>; Tue, 11 Dec 2001 02:06:47 -0500
17 Received: from wagner.rustcorp.com.au ([127.0.0.1] helo=rustcorp.com.au)
18 by wagner.rustcorp.com.au with esmtp (Exim 3.32 #1 (Debian))
19 id 16Dh0t-0003yl-00; Tue, 11 Dec 2001 18:07:39 +1100
20 From: Rusty Russell <rusty@rustcorp.com.au>
21 To: linux-kernel@vger.kernel.org
22 cc: lse-tech@lists.sourceforge.net
23 Subject: hackbench: New Multiqueue Scheduler Benchmark
24 Date: Tue, 11 Dec 2001 18:07:39 +1100
25 Message-Id: <E16Dh0t-0003yl-00@wagner.rustcorp.com.au>
26 Sender: linux-kernel-owner@vger.kernel.org
27 Precedence: bulk
28 X-Mailing-List: linux-kernel@vger.kernel.org
29 Status: RO
30 Content-Length: 4977
32 Hi all,
34 I've cut down the chat benchmark into a version which doesn't
35 use threads or semaphores, and called it hackbench:
37 On a 12-way PPC64:
38 2.4.17-pre7:
39 hackbench 50: Time: 851.469 Time: 847.143 Time: 826.868
41 2.4.17-pre7-multiqueue-patch:
42 hackbench 50: Time: 15.120 Time: 14.766 Time: 15.067
44 "hackbench 1" creates a group of 20 processes listening on a socket
45 each, and 20 writers: each of the writers writes 100 messages to each
46 socket (ie. 20 x 100 messages each).
48 "hackbench 50" simply runs 50 of these groups in parallel. You'd
49 expect it to be 5 times slower than hackbench 10, but without the
50 multiqueue patch:
52 10: Time: 10.573 Time: 13.471 Time: 9.289
53 50: Time: 851.469 Time: 847.143 Time: 826.868
55 Enjoy,
56 Rusty.
58 Anyone who quotes me in their sig is an idiot. -- Rusty Russell.
60 /* Test groups of 20 processes spraying to 20 receivers */
61 #include <stdio.h>
62 #include <string.h>
63 #include <errno.h>
64 #include <sys/types.h>
65 #include <sys/socket.h>
66 #include <sys/wait.h>
67 #include <sys/time.h>
68 #include <sys/poll.h>
70 #define DATASIZE 100
71 static unsigned int loops = 100;
72 static int use_pipes = 0;
74 static void barf(const char *msg)
76 fprintf(stderr, "%s (error: %s)\n", msg, strerror(errno));
77 exit(1);
80 static void fdpair(int fds[2])
82 if (use_pipes) {
83 if (pipe(fds) == 0)
84 return;
85 } else {
86 if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds) == 0)
87 return;
89 barf("Creating fdpair");
92 /* Block until we're ready to go */
93 static void ready(int ready_out, int wakefd)
95 char dummy;
96 struct pollfd pollfd = { .fd = wakefd, .events = POLLIN };
98 /* Tell them we're ready. */
99 if (write(ready_out, &dummy, 1) != 1)
100 barf("CLIENT: ready write");
102 /* Wait for "GO" signal */
103 if (poll(&pollfd, 1, -1) != 1)
104 barf("poll");
107 /* Sender sprays loops messages down each file descriptor */
108 static void sender(unsigned int num_fds,
109 int out_fd[num_fds],
110 int ready_out,
111 int wakefd)
113 char data[DATASIZE];
114 unsigned int i, j;
116 ready(ready_out, wakefd);
118 /* Now pump to every receiver. */
119 for (i = 0; i < loops; i++) {
120 for (j = 0; j < num_fds; j++) {
121 int ret, done = 0;
123 again:
124 ret = write(out_fd[j], data + done, sizeof(data)-done);
125 if (ret < 0)
126 barf("SENDER: write");
127 done += ret;
128 if (done < sizeof(data))
129 goto again;
134 /* One receiver per fd */
135 static void receiver(unsigned int num_packets,
136 int in_fd,
137 int ready_out,
138 int wakefd)
140 unsigned int i;
142 /* Wait for start... */
143 ready(ready_out, wakefd);
145 /* Receive them all */
146 for (i = 0; i < num_packets; i++) {
147 char data[DATASIZE];
148 int ret, done = 0;
150 again:
151 ret = read(in_fd, data + done, DATASIZE - done);
152 if (ret < 0)
153 barf("SERVER: read");
154 done += ret;
155 if (done < DATASIZE)
156 goto again;
160 /* One group of senders and receivers */
161 static unsigned int group(unsigned int num_fds,
162 int ready_out,
163 int wakefd)
165 unsigned int i;
166 unsigned int out_fds[num_fds];
168 for (i = 0; i < num_fds; i++) {
169 int fds[2];
171 /* Create the pipe between client and server */
172 fdpair(fds);
174 /* Fork the receiver. */
175 switch (fork()) {
176 case -1: barf("fork()");
177 case 0:
178 close(fds[1]);
179 receiver(num_fds*loops, fds[0], ready_out, wakefd);
180 exit(0);
183 out_fds[i] = fds[1];
184 close(fds[0]);
187 /* Now we have all the fds, fork the senders */
188 for (i = 0; i < num_fds; i++) {
189 switch (fork()) {
190 case -1: barf("fork()");
191 case 0:
192 sender(num_fds, out_fds, ready_out, wakefd);
193 exit(0);
197 /* Close the fds we have left */
198 for (i = 0; i < num_fds; i++)
199 close(out_fds[i]);
201 /* Return number of children to reap */
202 return num_fds * 2;
205 int main(int argc, char *argv[])
207 unsigned int i, num_groups, total_children;
208 struct timeval start, stop, diff;
209 unsigned int num_fds = 20;
210 int readyfds[2], wakefds[2];
211 char dummy;
213 if (argv[1] && strcmp(argv[1], "-pipe") == 0) {
214 use_pipes = 1;
215 argc--;
216 argv++;
219 if (argc != 2 || (num_groups = atoi(argv[1])) == 0)
220 barf("Usage: hackbench [-pipe] <num groups>\n");
222 fdpair(readyfds);
223 fdpair(wakefds);
225 total_children = 0;
226 for (i = 0; i < num_groups; i++)
227 total_children += group(num_fds, readyfds[1], wakefds[0]);
229 /* Wait for everyone to be ready */
230 for (i = 0; i < total_children; i++)
231 if (read(readyfds[0], &dummy, 1) != 1)
232 barf("Reading for readyfds");
234 gettimeofday(&start, NULL);
236 /* Kick them off */
237 if (write(wakefds[1], &dummy, 1) != 1)
238 barf("Writing to start them");
240 /* Reap them all */
241 for (i = 0; i < total_children; i++) {
242 int status;
243 wait(&status);
244 if (!WIFEXITED(status))
245 exit(1);
248 gettimeofday(&stop, NULL);
250 /* Print time... */
251 timersub(&stop, &start, &diff);
252 printf("Time: %lu.%03lu\n", diff.tv_sec, diff.tv_usec/1000);
253 exit(0);
256 To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
257 the body of a message to majordomo@vger.kernel.org
258 More majordomo info at http://vger.kernel.org/majordomo-info.html
259 Please read the FAQ at http://www.tux.org/lkml/