057dd615ba
- ESTEX WRITE ($14) на успехе возвращает DE=0, а НЕ счётчик записанного (вопреки докам; solid-c в своём fflush тоже отключил сравнение по счётчику) — write() теперь судит по CF/A: CF=0&A=0 → n, CF=0&A!=0 → ENOSPC/-1 - DSS выдаёт 8 манипуляторов (fd 2..9; fd 1 держит шелл под запущенный exe), а 9-й OPEN не возвращает 06h — ВЕШАЕТ систему; предохранитель _fd_guard: счётчик в open()/close(), отказ EMFILE без захода в DSS - tests/fdmax — эмпирика лимита (8 хендлов, затем EMFILE=6); tests/fbench — бенчмарк буферизации (floor 512-байтными read, оценка небуферизованного по 1-байтным, fgetc/fgets/fputc) - filetest расширен: raw-probe возврата write, сценарий r+ (чтение-запись-чтение с инвалидацией буфера), ungetc, fprintf Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
86 lines
3.0 KiB
C
86 lines
3.0 KiB
C
/*
|
||
* fbench — бенчмарк буферизации FILE* (вариант B+) с опорными замерами.
|
||
*
|
||
* 0a. read() блоками по 512 — «пол»: чистая скорость диск+syscall,
|
||
* ровно те же вызовы, что делает буферный слой изнутри;
|
||
* 0b. read() по 1 байту (16 КБ) — имитация НЕбуферизованного fgetc,
|
||
* ×6.25 даёт оценку на весь файл;
|
||
* 1. fgetc по всему файлу (102400 байт);
|
||
* 2. fgets построчно;
|
||
* 3. fputc 32 КБ (буфер: ~64 write-syscall'а вместо 32768).
|
||
*
|
||
* Интерпретация: если (1) ≈ (0a) — буферизация упирается в диск и
|
||
* работает идеально; выигрыш против небуферизованного = (0b)×6.25 − (1).
|
||
* Время — time(), секундная гранулярность. На дискете доминирует FDD;
|
||
* для чистого замера скопировать fbench.exe + big.txt на HDD (C:).
|
||
*/
|
||
|
||
#include <stdio.h>
|
||
#include <fcntl.h>
|
||
#include <unistd.h>
|
||
#include <time.h>
|
||
|
||
static char blk[512];
|
||
static char line[128];
|
||
|
||
int main(void)
|
||
{
|
||
long n;
|
||
int c, fd, r;
|
||
time_t t0, t1;
|
||
|
||
/* ----- 0a. Пол: блочный read по 512 ----- */
|
||
fd = open("BIG.TXT", O_RDONLY);
|
||
if (fd < 0) { puts("BIG.TXT not found"); return 1; }
|
||
t0 = time(NULL);
|
||
n = 0;
|
||
while ((r = read(fd, blk, 512)) > 0) n += r;
|
||
t1 = time(NULL);
|
||
printf("read512: %ld bytes, %ld s (floor)\n", n, (long)(t1 - t0));
|
||
close(fd);
|
||
|
||
/* ----- 0b. Имитация небуферизованного fgetc: read по 1 байту ----- */
|
||
fd = open("BIG.TXT", O_RDONLY);
|
||
t0 = time(NULL);
|
||
for (n = 0; n < 16384L; n++) {
|
||
if (read(fd, blk, 1) != 1) break;
|
||
}
|
||
t1 = time(NULL);
|
||
printf("read1 : %ld bytes, %ld s (x6.25 = unbuffered est.)\n",
|
||
n, (long)(t1 - t0));
|
||
close(fd);
|
||
|
||
/* ----- 1. fgetc по всему файлу ----- */
|
||
FILE *fp = fopen("BIG.TXT", "r");
|
||
if (!fp) { puts("fopen failed"); return 1; }
|
||
t0 = time(NULL);
|
||
n = 0;
|
||
while ((c = fgetc(fp)) != EOF) n++;
|
||
t1 = time(NULL);
|
||
printf("fgetc : %ld bytes, %ld s\n", n, (long)(t1 - t0));
|
||
|
||
/* ----- 2. fgets построчно ----- */
|
||
rewind(fp);
|
||
t0 = time(NULL);
|
||
n = 0;
|
||
while (fgets(line, sizeof(line), fp)) n++;
|
||
t1 = time(NULL);
|
||
printf("fgets : %ld lines, %ld s\n", n, (long)(t1 - t0));
|
||
fclose(fp);
|
||
|
||
/* ----- 3. fputc 32 КБ ----- */
|
||
fp = fopen("FBENCH.TMP", "w");
|
||
if (!fp) { puts("cannot create FBENCH.TMP"); return 1; }
|
||
t0 = time(NULL);
|
||
for (n = 0; n < 32768L; n++) {
|
||
if (fputc('x', fp) == EOF) { puts("fputc error"); return 1; }
|
||
}
|
||
if (fclose(fp)) { puts("fclose error"); return 1; }
|
||
t1 = time(NULL);
|
||
printf("fputc : 32768 bytes, %ld s\n", (long)(t1 - t0));
|
||
unlink("FBENCH.TMP");
|
||
|
||
puts("fbench done.");
|
||
return 0;
|
||
}
|