Skip to content

Instantly share code, notes, and snippets.

@wridgers
Last active January 25, 2019 00:58
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save wridgers/02c6cd5edf39e36151c52ca19eb96dcf to your computer and use it in GitHub Desktop.
; nasm -f elf64 yes.asm
; gcc -o yes yes.o
; ./yes | pv -a > /dev/null
global main
section .text
main:
mov rdi, 1
mov rsi, msg
mov rdx, msg.len
loop:
mov rax, 1
syscall
jmp loop
section .data
msg: times 16384 db "y",10
.len: equ $ - msg
// gcc -O3 -pipe -march=native -mtune=native yes.c -o yes
// ./yes | pv -a > /dev/null
#include <unistd.h>
#define LEN 1 << 15
int main() {
char str[LEN];
for (int i = 0; i < LEN; i += 2) {
str[i] = 'y';
str[i+1] = '\n';
}
while (write(1, str, LEN));
}
@wridgers
Copy link
Author

wridgers commented Jan 23, 2019

will@desktop [21:57:56] [~/src/yes] 
-> % yes | pv -a > /dev/null
[ 7.1GiB/s]

will@desktop [21:58:49] [~/src/yes] 
-> % ./yes-c | pv -a > /dev/null 
[7.47GiB/s]

will@desktop [22:00:58] [~/src/yes] 
-> % ./yes-asm | pv -a > /dev/null
[8.43GiB/s]

@cevans-uk
Copy link

Your asm version wouldn't work for me at home either.

Issue with the c version was:

$ diff -u yes.c yes-fixed.c 
--- yes.c	2019-01-24 17:27:31.917502162 +0000
+++ yes-fixed.c	2019-01-24 17:24:45.476245903 +0000
@@ -6,11 +6,11 @@
 #define LEN 1 << 15
 
 int main() {
-	char* str[LEN];
+	char str[LEN];
 
 	for (int i = 0; i < LEN; i += 2) {
-		str[i] = "y";
-		str[i+1] = "\n";
+		str[i] = 'y';
+		str[i+1] = '\n';
 	}
 
 	while (write(1, str, LEN));
// gcc -ldl -shared -D_GNU_SOURCE -Wall -O3 -o ld_yes.so ld_yes.c
// echo 1 | LD_PRELOAD=./ld_yes.so pv -C -a >/dev/null
//    `pv -C` to force `read` instead of `splice`
//    `echo 1` to make `select` work without monkey patching

#include <dlfcn.h>
#include <unistd.h>

ssize_t read(int fd, void *buf, size_t count) {
	static ssize_t (*read_)(int, void *, size_t) = NULL;
	if (read_ == NULL)
		read_ = (ssize_t (*)()) dlsym(RTLD_NEXT, "read");
	if (fd || count < 2)
		return read_(fd, buf, count);

	char *cbuf = (char *)buf;
	count = count & -2;
	for (int i = 0; i < count; i += 2) {
		cbuf[i] = 'y';
		cbuf[i+1] = '\n';
	}
	return count;
}
$ ./yes-c  | pv -a >/dev/null
[6.27GiB/s]
$ echo 1 | LD_PRELOAD=./ld_yes.so pv -C -a >/dev/null
[22.1GiB/s]

@wridgers
Copy link
Author

I fixed the asm version. Should work now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment