Tell me more ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I am neither concerned about RAM usage (as I've got enough) nor about losing data in case of an accidental shut-down (as my power is backed, the system is reliable and the data are not critical). But I do a lot of file processing and could use some performance boost.

That's why I'd like to set the system up to use more RAM for file system read and write caching, to prefetch files aggressively (e.g. read-ahead the whole file accessed by an application in case the file is of sane size or at least read-ahead a big chunk of it otherwise) and to flush writing buffers less frequently. How to achieve this (may it be possible)?

I use ext3 and ntfs (I use ntfs a lot!) file systems with XUbuntu 11.10 x86.

share|improve this question
Do you have a raid-controller or a "normal" disc controller capable of doing write-ahead? – Nils Mar 18 '12 at 20:37
3  
If you have lots of RAM, care a lot about performance and don't care about data loss, just copy all your data to a RAM disk and serve it from there, discarding all updates on crash/shutdown. If that won't work for you, you may need to qualify "enough" for RAM or how critical the data isn't. – James Youngman Mar 19 '12 at 0:16
@Nils, the computer is a laptop, so, I believe, the controller is pretty ordinary. – Ivan Mar 19 '12 at 0:17
So the controller won`t help you here. Can you comment on the answers how the according settings improved your throughput? – Nils Mar 19 '12 at 21:57

5 Answers

If you want to reserve memory for cache and buffer:

echo 10 > /proc/sys/vm/vfs_cache_pressure
# 100 is the default value. 
# Then you can limit the maximum amount of ram used by each app:
echo 8192 > /proc/sys/vm/max_map_count. 

I also recommend a swapiness=30 and high /proc/sys/vm/dirty_writeback_centisecs and /proc/sys/vm/dirty_expire_centisecs values (both: 1250). It can also help to tweak the file system:

echo 8192 > /sys/block/mmcblk0/queue/max_sectors_kb
echo 8192 > /sys/block/mmcblk1/queue/max_sectors_kb
echo 0 > /sys/block/mmcblk0/queue/iosched/slice_idle
echo 0 > /sys/block/mmcblk1/queue/iosched/slice_idle
echo 160 > /sys/block/mmcblk0/queue/iosched/quantum
echo 160 > /sys/block/mmcblk1/queue/iosched/quantum
echo 800 > /sys/block/mmcblk0/queue/iosched/fifo_expire_sync
echo 800 > /sys/block/mmcblk1/queue/iosched/fifo_expire_sync
echo 180 > /sys/block/mmcblk0/queue/iosched/fifo_expire_async
echo 180 > /sys/block/mmcblk1/queue/iosched/fifo_expire_async
echo 1 > /sys/block/mmcblk0/queue/iosched/back_seek_penalty 
echo 1 > /sys/block/mmcblk1/queue/iosched/back_seek_penalty

Here is my full tweak for a laptop (laptop mode=5):

# Speed Einstellungen
# Bei Wieviel Prozent freien Speicher soll das System anfange zu swappen
echo 40 > /proc/sys/vm/swappiness

echo 1250 > /proc/sys/vm/dirty_writeback_centisecs

# Wie alt muessen "dirty changes" sein damit sie weg geschrieben werden
# Sinnvollerweise vm.dirty_expire_centisecs = vm.dirty_writeback_centisecs
echo 1250 > /proc/sys/vm/dirty_expire_centisecs

# Wie viel Prozent das RAMS duerfen von einem Prozess mir "dirty changes"  
# gefuellt
# sein bevor der Prozess gezwungen wird diese Aenderungen zu schreiben 40:10
echo 10 > /proc/sys/vm/dirty_ratio

# Diese aktiviert oder deaktiviert die Toetung der OOM-Triggerung Aufgabe in
# Out-of-Memory-Situationen. Verbessert die Stabilität.
echo 1 > /proc/sys/vm/oom_kill_allocating_task

# vm.vfs_cache_pressure (0-250, 100 ist Standard) welche festlegt ob und wie
# sehr Prozesse ausgeswappt werden um Arbeitsspeicher fuer Cache frei zu  
# machen. 
echo 10 > /proc/sys/vm/vfs_cache_pressure

# default 0
echo 5 > /proc/sys/vm/laptop_mode

# default 22
echo 30 > /proc/sys/vm/lowmem_reserve_ratio

# vm.overcommit_memory (0=default, 1=malloc always succeeds(?!?), 2=strict 
overcommit)
# vm.overcommit_ratio (50=default, I used 100)
echo 2 > /proc/sys/vm/overcommit_memory
echo 100 > /proc/sys/vm/overcommit_ratio

# default 5
echo 2 > /proc/sys/vm/page-cluster

# min free ram
echo 512 > /proc/sys/vm/min_free_kbytes

# max ram for an app
echo 8192 > /proc/sys/vm/max_map_count

# default 250 32000 32 128
# 4096 512000 1600 2048
# 500 512000 64 2048
echo 4096 512000 1600 2048 > /proc/sys/kernel/sem

# default 128
echo 16 > /sys/block/sda/queue/nr_requests
echo 16 > /sys/block/sdb/queue/nr_requests

echo 8192 > /sys/block/sda/queue/read_ahead_kb
echo 8192 > /sys/block/sdb/queue/read_ahead_kb 

# Set Readahead to a higher value
# Default: 256
blockdev --setfra 8192 /dev/sda
blockdev --setfra 8192 /dev/sdb

# default 512
echo 8192 > /sys/block/sda/queue/max_sectors_kb
echo 8192 > /sys/block/sdb/queue/max_sectors_kb
share|improve this answer
If I haven't misunderstood the "iosched/quantum" setting is the number of IO requests on-the-fly. Setting it as high as 160 may cause heavy latency. Personally I've got pretty good performance with values in range 2-20 with lower values improving latency but decreasing throughput. – Mikko Rantalainen Jun 28 '12 at 10:27
What is the default settings? – Phpdna Jun 28 '12 at 10:30
The kernel default for quantum is 4. – Mikko Rantalainen Jun 28 '12 at 12:01
1  
max_map_count controls the maximum number of memory map areas a process may have. I don't see how it can affect performance. – CyberShadow Jan 26 at 16:15
1  
Well, reading the official documentation before changing kernel parameters is always a good idea! – CyberShadow Jan 26 at 16:47
show 6 more comments

Firstly, I DO NOT recommend you continue using NTFS, as ntfs implemention in Linux would be performance and security trouble at any time.

There are several things you can do:

  • use some newer fs such as ext4 or btrfs
  • try to change your io scheduler, for example bfq
  • turn off swap
  • use some automatic preloader like preload
  • use something like systemd to preload while booting
  • ... and something more

Maybe you want to give it a try :-)

share|improve this answer
I've already moved entirely away from NTFS to ext4 once, leaving the only NTFS partition to be the Windows system partition. But it turned in many inconveniences for me and I have turned back to NTFS as the main data partition (where I store all my documents, downloads, projects, source code etc.) file system. I don't give up rethinking my partitions structure and my workflow (to use less Windows) but right now giving up NTFS doesn't seem a realistic option. – Ivan Feb 3 '12 at 12:39
If you have to use your data inside Windows too, NTFS may be the only option. (many other options available if you can use your Windows just as a VM inside linux) – Felix Yan Feb 3 '12 at 12:41

Read ahead:

On 32 bit systems:

blockdev --setra 8388607 /dev/sda

On 64 bit systems:

blockdev --setra 4294967295 /dev/sda

Write behind cache:

echo 100 > /proc/sys/vm/dirty_ratio

This will use up to 100% of your free memory as write cache.

Or you can go all out and use tmpfs. This is only relevant if you have RAM enough. Put this in /etc/fstab. Replace 100G with the amount of physical RAM.

tmpfs /mnt/tmpfs tmpfs size=100G,rw,nosuid,nodev 0 0

Then:

mkdir /mnt/tmpfs; mount -a

Then use /mnt/tmpfs.

share|improve this answer

You can set the read-ahead size with blockdev --setra sectors /dev/sda1, where sectors is the size you want in 512 byte sectors.

share|improve this answer

Improving disk cache performance in general is more than just increasing the file system cache size unless your whole system fits the in RAM in which case you should use RAM drive (tmpfs is good because it allows falling back to disk if you need the RAM in some case) for runtime storage (and perhaps an initrd script to copy system from storage to RAM drive at startup).

You didn't tell if your storage device is SSD or HDD. Here's what I've found to work for me (in my case sda is a HDD mounted at /home and sdb is SSD mounted at /).

First optimize the load-stuff-from-storage-to-cache part:

Here's my setup for HDD (make sure AHCI+NCQ is enabled in BIOS if you have toggles):

echo cfq > /sys/block/sda/queue/scheduler
echo 10000 > /sys/block/sda/queue/iosched/fifo_expire_async
echo 250 > /sys/block/sda/queue/iosched/fifo_expire_sync
echo 80 > /sys/block/sda/queue/iosched/slice_async
echo 1 > /sys/block/sda/queue/iosched/low_latency
echo 6 > /sys/block/sda/queue/iosched/quantum
echo 5 > /sys/block/sda/queue/iosched/slice_async_rq
echo 3 > /sys/block/sda/queue/iosched/slice_idle
echo 100 > /sys/block/sda/queue/iosched/slice_sync
hdparm -q -M 254 /dev/sda

Worth noting for the HDD case is high fifo_expire_async (usually write) and long slice_sync to allow a single process to get high throughput (set slice_sync to lower number if you hit situations where multiple processes are waiting for some data from the disk in parallel). The slice_idle is always a compromise for HDDs but setting it somewhere in range 3-20 should be okay depending on disk usage and disk firmware. I prefer to target for low values but setting it too low will destroy your throughput. The quantum setting seems to affect throughput a lot but try to keep this as low as possible to keep latency on sensible level. Setting quantum too low will destroy throughput. Values in range 3-8 seem to work well with HDDs. The worst case latency for a read is (quantum * slice_sync) + (slice_async_rq * slice_async) ms if I've understood the kernel behavior correctly. The async is mostly used by writes and since you're willing to delay writing to disk, set both slice_async_rq and slice_async to very low numbers. However, setting slice_async_rq too low value may stall reads because writes cannot be delayed after reads any more. My config will try to write data to disk at most after 10 seconds after data has been passed to kernel but since you can tolerate loss of data on power loss also set fifo_expire_async to 3600000 to tell that 1 hour is okay for the delay to disk. Just keep the slice_async low, though, because otherwise you can get high read latency.

The hdparm command is required to prevent AAM from killing much of the performance that AHCI+NCQ allows. If your disk makes too much noise, then skip this.

Here's my setup for SSD (Intel 320 series):

echo cfq > /sys/block/sdb/queue/scheduler
echo 1 > /sys/block/sdb/queue/iosched/back_seek_penalty
echo 10000 > /sys/block/sdb/queue/iosched/fifo_expire_async
echo 20 > /sys/block/sdb/queue/iosched/fifo_expire_sync
echo 1 > /sys/block/sdb/queue/iosched/low_latency
echo 6 > /sys/block/sdb/queue/iosched/quantum
echo 2 > /sys/block/sdb/queue/iosched/slice_async
echo 10 > /sys/block/sdb/queue/iosched/slice_async_rq
echo 1 > /sys/block/sdb/queue/iosched/slice_idle
echo 20 > /sys/block/sdb/queue/iosched/slice_sync

Here it's worth noting the low values for different slice settings. The most important setting for an SSD is slice_idle which must be set to 0-1. Setting it to zero moves all ordering decisions to native NCQ while setting it to 1 allows kernel to order requests (but if the NCQ is active, the hardware may override kernel ordering partially). Test both values to see if you can see the difference. For Intel 320 series, it seems that setting slide_idle to 0 gives the best throughput but setting it to 1 gives best (lowest) overall latency.

For more information about these tunables, see http://www.linux-mag.com/id/7572/.

Now that we have configured kernel to load stuff from disk to cache with sensible performance, it's time to adjust the cache behavior:

According to benchmarks I've done, I wouldn't bother setting read ahead via blockdev at all.

Set system to prefer swapping file data over application code (this does not matter if you have enough RAM to keep whole filesystem and all the application code and all virtual memory allocated by applications in RAM). This reduces latency for swapping between different applications over latency for accessing big files from a single application:

echo 15 > /proc/sys/vm/swappiness

Do not ever set this to 0 but if you prefer to keep applications pretty much always in RAM you could set this to 1. If you were memory limited and working with big files (e.g. HD video editing), then it might make sense to set this close to 100.

Next, tell kernel to prefer keeping directory hierarchy in memory over file contents in case some RAM needs to be freed (again, if everything fits in RAM, this setting does nothing):

echo 10 > /proc/sys/vm/vfs_cache_pressure

Setting vfs_cache_pressure to low value makes sense because in most cases, the kernel needs to know the directory structure before it can use file contents from the cache and flushing the directory cache too soon will make the file cache next to worthless. Consider going all the way down to 1 with this setting if you have lots of files. Setting this to big value is sensible only if you have only a few big files that are constantly being re-read.

Finally tell the kernel to use up to 99% of the RAM as cache for writes and instruct kernel to use up to 50% of RAM before slowing down the process that's writing (default for dirty_background_ratio is 10).

echo 99 > /proc/sys/vm/dirty_ratio
echo 50 > /proc/sys/vm/dirty_background_ratio

And tell that 1h write delay is ok to even start writing stuff on the disk:

echo 360000 > /proc/sys/vm/dirty_expire_centisecs
echo 360000 > /proc/sys/vm/dirty_writeback_centisecs

If you put all of those to /etc/rc.local and include following at the end, everything will be in cache as soon as possible after boot:

(nice find / -type f -and -not -path '/sys/*' -and -not -path '/proc/*' -print0 2>/dev/null | nice ionice -c 3 wc -l --files0-from - > /dev/null)&

Or a bit simpler alternative which might work better (cache only /home and /usr):

(nice find /home /usr -type f -print0 | nice ionice -c 3 wc -l --files0-from - > /dev/null)&
share|improve this answer
First, 15 swapiness is extremly low and doesn't work for Maemo device and also very high dirty_expire_centisecs I don't it will work on Maemo. High fifo_expire_async and long slice_sync is interesting. – Phpdna Jul 27 '12 at 13:36
2  
A well-informed and overall much better answer than the accepted one! This one is underrated... I guess most people just want simple instructions without bothering to understand what they really do... – CyberShadow Jan 26 at 18:17
@Phpdevpad: Perhaps there's something wrong with Meamo's kernel? I have only android devices and 15 is totally fine for AMRv6 and ARMv7 devices. The swappiness setting is supposed to tune the swapping balance--it should never prevent or force swapping if the kernel is running correctly. – Mikko Rantalainen Jan 28 at 7:03
1  
@Phpdevpad: In addition, the question said "I am neither concerned about RAM usage [...]"--I don't think any Maemo device qualifies. – Mikko Rantalainen Jan 28 at 7:11
@MikkoRantalainen: I'm not in love with Linux and if you feel you are answer is technical better then go with it. I have very good experienced with my settings on a maemo devices and on other boxes. Period. Also dabbling around with kernel parameters is dangerous so my tuneing parameters is for people who also like to read more. If you say it's for people that want cut and paste I'm fine with it. BTW. If I write 2 different positions in my answer or comments etc. or error or anything it's mostly an error and also most likely I'm not payed like you. – Phpdna Jan 28 at 8:44
show 1 more comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.