blob: c0d713cc8c245ce03f28cbc7b0d6403e81c7a216 [file] [log] [blame]
nstraz8dbb34c2001-12-12 22:32:31 +00001From linux-kernel-owner@vger.kernel.org Tue Dec 11 01:11:36 2001
2Received: 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)
3Received: 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)
10Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand
11 id <S284902AbRLKHHQ>; Tue, 11 Dec 2001 02:07:16 -0500
12Received: (majordomo@vger.kernel.org) by vger.kernel.org
13 id <S284914AbRLKHG5>; Tue, 11 Dec 2001 02:06:57 -0500
14Received: 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
17Received: 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
20From: Rusty Russell <rusty@rustcorp.com.au>
21To: linux-kernel@vger.kernel.org
22cc: lse-tech@lists.sourceforge.net
23Subject: hackbench: New Multiqueue Scheduler Benchmark
24Date: Tue, 11 Dec 2001 18:07:39 +1100
25Message-Id: <E16Dh0t-0003yl-00@wagner.rustcorp.com.au>
26Sender: linux-kernel-owner@vger.kernel.org
27Precedence: bulk
28X-Mailing-List: linux-kernel@vger.kernel.org
29Status: RO
30Content-Length: 4977
31
32Hi all,
33
34 I've cut down the chat benchmark into a version which doesn't
35use threads or semaphores, and called it hackbench:
36
37On a 12-way PPC64:
382.4.17-pre7:
39 hackbench 50: Time: 851.469 Time: 847.143 Time: 826.868
40
412.4.17-pre7-multiqueue-patch:
42 hackbench 50: Time: 15.120 Time: 14.766 Time: 15.067
43
44"hackbench 1" creates a group of 20 processes listening on a socket
45each, and 20 writers: each of the writers writes 100 messages to each
46socket (ie. 20 x 100 messages each).
47
48"hackbench 50" simply runs 50 of these groups in parallel. You'd
49expect it to be 5 times slower than hackbench 10, but without the
50multiqueue patch:
51
5210: Time: 10.573 Time: 13.471 Time: 9.289
5350: Time: 851.469 Time: 847.143 Time: 826.868
54
55Enjoy,
56Rusty.
57--
58 Anyone who quotes me in their sig is an idiot. -- Rusty Russell.
59
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>
69
70#define DATASIZE 100
71static unsigned int loops = 100;
72static int use_pipes = 0;
73
74static void barf(const char *msg)
75{
76 fprintf(stderr, "%s (error: %s)\n", msg, strerror(errno));
77 exit(1);
78}
79
80static void fdpair(int fds[2])
81{
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;
88 }
89 barf("Creating fdpair");
90}
91
92/* Block until we're ready to go */
93static void ready(int ready_out, int wakefd)
94{
95 char dummy;
96 struct pollfd pollfd = { .fd = wakefd, .events = POLLIN };
97
98 /* Tell them we're ready. */
99 if (write(ready_out, &dummy, 1) != 1)
100 barf("CLIENT: ready write");
101
102 /* Wait for "GO" signal */
103 if (poll(&pollfd, 1, -1) != 1)
104 barf("poll");
105}
106
107/* Sender sprays loops messages down each file descriptor */
108static void sender(unsigned int num_fds,
109 int out_fd[num_fds],
110 int ready_out,
111 int wakefd)
112{
113 char data[DATASIZE];
114 unsigned int i, j;
115
116 ready(ready_out, wakefd);
117
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;
122
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;
130 }
131 }
132}
133
134/* One receiver per fd */
135static void receiver(unsigned int num_packets,
136 int in_fd,
137 int ready_out,
138 int wakefd)
139{
140 unsigned int i;
141
142 /* Wait for start... */
143 ready(ready_out, wakefd);
144
145 /* Receive them all */
146 for (i = 0; i < num_packets; i++) {
147 char data[DATASIZE];
148 int ret, done = 0;
149
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;
157 }
158}
159
160/* One group of senders and receivers */
161static unsigned int group(unsigned int num_fds,
162 int ready_out,
163 int wakefd)
164{
165 unsigned int i;
166 unsigned int out_fds[num_fds];
167
168 for (i = 0; i < num_fds; i++) {
169 int fds[2];
170
171 /* Create the pipe between client and server */
172 fdpair(fds);
173
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);
181 }
182
183 out_fds[i] = fds[1];
184 close(fds[0]);
185 }
186
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);
194 }
195 }
196
197 /* Close the fds we have left */
198 for (i = 0; i < num_fds; i++)
199 close(out_fds[i]);
200
201 /* Return number of children to reap */
202 return num_fds * 2;
203}
204
205int main(int argc, char *argv[])
206{
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;
212
213 if (argv[1] && strcmp(argv[1], "-pipe") == 0) {
214 use_pipes = 1;
215 argc--;
216 argv++;
217 }
218
219 if (argc != 2 || (num_groups = atoi(argv[1])) == 0)
220 barf("Usage: hackbench [-pipe] <num groups>\n");
221
222 fdpair(readyfds);
223 fdpair(wakefds);
224
225 total_children = 0;
226 for (i = 0; i < num_groups; i++)
227 total_children += group(num_fds, readyfds[1], wakefds[0]);
228
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");
233
234 gettimeofday(&start, NULL);
235
236 /* Kick them off */
237 if (write(wakefds[1], &dummy, 1) != 1)
238 barf("Writing to start them");
239
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);
246 }
247
248 gettimeofday(&stop, NULL);
249
250 /* Print time... */
251 timersub(&stop, &start, &diff);
252 printf("Time: %lu.%03lu\n", diff.tv_sec, diff.tv_usec/1000);
253 exit(0);
254}
255-
256To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
257the body of a message to majordomo@vger.kernel.org
258More majordomo info at http://vger.kernel.org/majordomo-info.html
259Please read the FAQ at http://www.tux.org/lkml/
260
261