CPU Pegged

I have a bandwidth monitoring script that I’d like to start running every half hour. It’s a fairly simple one (about 75-100 lines). The problem is that every time it runs it pegs the CPU at 100% for a few seconds until it’s done. I get a few dropped packets while the CPU is at 100%. Does anyone know any optimization tips for scripts or is there a way to lower its priority? Thanks.

BTW, I’m using version 3.22 on an RB1000.

BTW, you didn’t post the script - nothing to optimize =)

You’re right. I didn’t really want to post the whole script but if anyone wants to take a look, I’ll post it here. It’s very similar to some of the scripts in the Wiki but tailored for my purposes. I haven’t fully debugged and tested this yet so there may be some slight errors here and there but I wanted to figure out the CPU issue first before moving on. Here it is:

#Percentages of original speeds to reduce speeds by
:global adminLevels 100,100,75,60,45,30

#How often does this script run? (minutes * seconds)
:global totalSeconds (30 * 60)

#Percentage of the total possible bytes available this
#period can be used before a penalty kicks in
:global threshold 75

##############################################

:global i 0
:global maxAdminLevel ([:len $adminLevels] - 1)

:foreach i in=[/queue simple find comment !=""] do={
	:local rawComment [:toarray [/queue simple get $i comment]]

	:local customerID [:pick $rawComment 0]
	:local down [:tonum [:pick $rawComment 1]]
	:local up [:tonum [:pick $rawComment 2]]
	:local level [:tonum [:pick $rawComment 3]]
	:local bytesDown [:tonum [:pick $rawComment 4]]
	:local bytesUp [:tonum [:pick $rawComment 5]]

	:local rawBytes [/queue simple get $i bytes]
	/queue simple reset-counters $i

	:local delimPos [:find $rawBytes "/"]
	:local curUpBytes [:pick $rawBytes 0 $delimPos]
	:local curDownBytes [:pick $rawBytes ($delimPos + 1) [:len $rawBytes]]

	:local totalUpBytes ($curUpBytes * 8)
	:local totalDownBytes ($curDownBytes * 8)

	:local newBytesUp ($bytesUp + $curUpBytes)
	:local newBytesDown ($bytesDown + $curDownBytes)

	:local adjustedPossibleDownBytes ((($down * 1024 * $totalSeconds) * $threshold) / 100)
	:local adjustedPossibleUpBytes ((($up * 1024 * $totalSeconds) * $threshold) / 100)
	
	:global hasPenalty 0
	:global hasForgiveness 0

	:if ([$totalDownBytes] >=$adjustedPossibleDownBytes) do={
		:global hasPenalty 1
	} else={
		:if ([$totalUpBytes] >=$adjustedPossibleUpBytes) do={
			:global hasPenalty 1
		} else={
			:global hasForgiveness 1
		}
	}

	:if ([$hasPenalty] =1) do={
		:if ([$level] <$maxAdminLevel) do={
			:local newLevel ($level + 1)
			:local newAdminLevel [:pick $adminLevels $newLevel]
			:local newDown ((($down * $newAdminLevel) / 100) * 1024)
			:local newUp ((($up * $newAdminLevel) / 100) * 1024)

			:local newComment ($customerID, $down, $up, $newLevel, $newBytesDown, $newBytesUp)

			/queue simple set $i max-limit="$newUp/$newDown" comment=$newComment
		} else={
			:local bytesComment ([:pick $rawComment 0 4], $newBytesDown, $newBytesUp)
			/queue simple set $i comment=$bytesComment
		}
	}

	:if ([$hasForgiveness] =1) do={
		:if ([$level] >0) do={
			:local newDown ($down * 1024)
			:local newUp ($up * 1024)

			:local newComment ($customerID, $down, $up, 0, $newBytesDown, $newBytesUp)

			/queue simple set $i max-limit="$newUp/$newDown" comment=$newComment
		} else={
			:local bytesComment ([:pick $rawComment 0 4], $newBytesDown, $newBytesUp)
			/queue simple set $i comment=$bytesComment
		}
	}
}

Well, by inserting a delay every tenth iteration as I loop over the queues, I can keep the CPU from going to 100%, however, I still get significant, unexplained packet loss to the router while I run this script. Does anyone have any idea what to look for to troubleshoot this? Mikrotik? I’m stuck. Thanks all.

If you have a lot of queues it will be very slow to search through every queue.
You need faster CPU.