89d95fc73b
* fix: Windows port audit fixes — _FILE_OFFSET_BITS guard, O_BINARY st.h, getrusage peak, oracle diagnostic, setup.sh wmic
Audit remediation (all MEDIUM issues fixed):
- compat.h: compile-time #error if _FILE_OFFSET_BITS < 64 on _WIN32
- compat.h: COMPAT_O_RDONLY macro (O_RDONLY|O_BINARY on Windows, belt-and-braces)
- st.h: use COMPAT_O_RDONLY in both open() call sites (plan §1 row 1)
- compat.h: getrusage shim now uses PeakWorkingSetSize (ru_maxrss = peak, not current)
- glm.c: oracle mismatch diagnostic — prints position/expected/got on TF failures
- setup.sh: replace deprecated wmic with /proc/meminfo (MSYS2 provides it)
- .gitignore: *.exe, glm_tiny/, olmoe_hf/, olmoe_i4/
LOW issues addressed:
- _FILE_OFFSET_BITS guard prevents silent 32-bit off_t wrap at >4GB offsets
- coli Windows venv path (Scripts/python.exe) fixed earlier
- posix_fadvise do{}while(0) kept intentionally — no caller checks return code
Verification: oracle 32/32, 27/27 Python tests, rename EEXIST, >4GB pread offset.
* docs: add Windows 11 native port section to README
- Toolchain: MinGW-w64 (winlibs or MSYS2), GCC 16.1 tested
- Build instructions: make glm.exe, tiny oracle verification
- Runtime: SNAP=..., coli chat, coli serve all work
- Status: Phase 1 complete (compiles, correct, static-linked)
- Update platform requirements to include Windows 11 natively
60 lines
2.4 KiB
C
60 lines
2.4 KiB
C
/* Microbench: banda in lettura RANDOM con blocchi tipo-expert (~19 MB int4).
|
|
* Misura cio' che fa il motore davvero: N thread che leggono in parallelo
|
|
* (expert_load sotto omp parallel for), buffered oppure O_DIRECT.
|
|
* uso: ./iobench <file_grande> [blocco_MB] [n_letture] [threads] [direct 0/1]
|
|
* build: gcc -O2 -fopenmp iobench.c -o iobench */
|
|
#define _GNU_SOURCE
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <stdint.h>
|
|
#include <fcntl.h>
|
|
#include <unistd.h>
|
|
#include <time.h>
|
|
#include <errno.h>
|
|
#include <string.h>
|
|
#include "compat.h"
|
|
#ifdef _OPENMP
|
|
#include <omp.h>
|
|
#endif
|
|
static double now(){ struct timespec t; clock_gettime(CLOCK_MONOTONIC,&t); return t.tv_sec+t.tv_nsec*1e-9; }
|
|
int main(int argc,char**argv){
|
|
if(argc<2){fprintf(stderr,"uso: %s file [blkMB] [n] [threads] [direct 0/1]\n",argv[0]);return 1;}
|
|
long blk=(argc>2?atol(argv[2]):19)*1024*1024;
|
|
int n=argc>3?atoi(argv[3]):64;
|
|
int nth=argc>4?atoi(argv[4]):8;
|
|
int direct=argc>5?atoi(argv[5]):1;
|
|
#ifdef O_DIRECT
|
|
int fd=open(argv[1],O_RDONLY|(direct?O_DIRECT:0));
|
|
if(fd<0 && direct){ fprintf(stderr,"O_DIRECT non disponibile (%s), uso buffered\n",strerror(errno));
|
|
direct=0; fd=open(argv[1],O_RDONLY); }
|
|
#else
|
|
int fd=open(argv[1],O_RDONLY); /* macOS: F_NOCACHE ~ O_DIRECT */
|
|
#ifdef __APPLE__
|
|
if(direct && fd>=0) fcntl(fd,F_NOCACHE,1);
|
|
#else
|
|
if(direct){ fprintf(stderr,"O_DIRECT non disponibile, uso buffered\n"); direct=0; }
|
|
#endif
|
|
#endif
|
|
if(fd<0){perror("open");return 1;}
|
|
off_t sz=lseek(fd,0,SEEK_END);
|
|
if(sz<blk*2){fprintf(stderr,"file troppo piccolo\n");return 1;}
|
|
/* offset random pre-generati (stessi per ogni configurazione: srand fisso) */
|
|
off_t *offs=malloc(n*sizeof(off_t)); srand(1234);
|
|
for(int i=0;i<n;i++){ off_t o=((off_t)rand()*4096)%(sz-blk); offs[i]=o&~4095L; }
|
|
double t0=now(); long tot=0;
|
|
#pragma omp parallel num_threads(nth) reduction(+:tot)
|
|
{
|
|
void *buf; if(posix_memalign(&buf,4096,blk)){perror("memalign");exit(1);}
|
|
#pragma omp for schedule(dynamic,1)
|
|
for(int i=0;i<n;i++){
|
|
ssize_t r=pread(fd,buf,blk,offs[i]);
|
|
if(r<0) perror("pread"); else tot+=r;
|
|
}
|
|
free(buf);
|
|
}
|
|
double dt=now()-t0;
|
|
printf("%s x%d thread: %d letture x %ldMB = %.1f GB in %.2fs -> %.2f GB/s (%.1f ms/blocco effettivi)\n",
|
|
direct?"O_DIRECT":"buffered", nth, n, blk/1024/1024, tot/1e9, dt, tot/1e9/dt, dt/n*1000);
|
|
close(fd); free(offs); return 0;
|
|
}
|